1 /* com.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
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);
88 #include "output.h" /* Must follow tree.h so TREE_CODE is defined! */
91 #include "diagnostic.h"
92 #include "langhooks.h"
93 #include "langhooks-def.h"
95 /* VMS-specific definitions */
98 #define O_RDONLY 0 /* Open arg for Read/Only */
99 #define O_WRONLY 1 /* Open arg for Write/Only */
100 #define read(fd,buf,size) VMS_read (fd,buf,size)
101 #define write(fd,buf,size) VMS_write (fd,buf,size)
102 #define open(fname,mode,prot) VMS_open (fname,mode,prot)
103 #define fopen(fname,mode) VMS_fopen (fname,mode)
104 #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
105 #define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
106 #define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
107 static int VMS_fstat (), VMS_stat ();
108 static char * VMS_strncat ();
109 static int VMS_read ();
110 static int VMS_write ();
111 static int VMS_open ();
112 static FILE * VMS_fopen ();
113 static FILE * VMS_freopen ();
114 static void hack_vms_include_specification ();
115 typedef struct { unsigned :16, :16, :16; } vms_ino_t;
116 #define ino_t vms_ino_t
117 #define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
120 #define FFECOM_DETERMINE_TYPES 1 /* for com.h */
137 /* Externals defined here. */
139 /* Stream for reading from the input file. */
142 /* These definitions parallel those in c-decl.c so that code from that
143 module can be used pretty much as is. Much of these defs aren't
144 otherwise used, i.e. by g77 code per se, except some of them are used
145 to build some of them that are. The ones that are global (i.e. not
146 "static") are those that ste.c and such might use (directly
147 or by using com macros that reference them in their definitions). */
149 tree string_type_node;
151 /* The rest of these are inventions for g77, though there might be
152 similar things in the C front end. As they are found, these
153 inventions should be renamed to be canonical. Note that only
154 the ones currently required to be global are so. */
156 static tree ffecom_tree_fun_type_void;
158 tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
159 tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
160 tree ffecom_integer_one_node; /* " */
161 tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
163 /* _fun_type things are the f2c-specific versions. For -fno-f2c,
164 just use build_function_type and build_pointer_type on the
165 appropriate _tree_type array element. */
167 static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
168 static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
169 static tree ffecom_tree_subr_type;
170 static tree ffecom_tree_ptr_to_subr_type;
171 static tree ffecom_tree_blockdata_type;
173 static tree ffecom_tree_xargc_;
175 ffecomSymbol ffecom_symbol_null_
184 ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
185 ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
187 int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
188 tree ffecom_f2c_integer_type_node;
189 tree ffecom_f2c_ptr_to_integer_type_node;
190 tree ffecom_f2c_address_type_node;
191 tree ffecom_f2c_real_type_node;
192 tree ffecom_f2c_ptr_to_real_type_node;
193 tree ffecom_f2c_doublereal_type_node;
194 tree ffecom_f2c_complex_type_node;
195 tree ffecom_f2c_doublecomplex_type_node;
196 tree ffecom_f2c_longint_type_node;
197 tree ffecom_f2c_logical_type_node;
198 tree ffecom_f2c_flag_type_node;
199 tree ffecom_f2c_ftnlen_type_node;
200 tree ffecom_f2c_ftnlen_zero_node;
201 tree ffecom_f2c_ftnlen_one_node;
202 tree ffecom_f2c_ftnlen_two_node;
203 tree ffecom_f2c_ptr_to_ftnlen_type_node;
204 tree ffecom_f2c_ftnint_type_node;
205 tree ffecom_f2c_ptr_to_ftnint_type_node;
207 /* Simple definitions and enumerations. */
209 #ifndef FFECOM_sizeMAXSTACKITEM
210 #define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
211 larger than this # bytes
212 off stack if possible. */
215 /* For systems that have large enough stacks, they should define
216 this to 0, and here, for ease of use later on, we just undefine
219 #if FFECOM_sizeMAXSTACKITEM == 0
220 #undef FFECOM_sizeMAXSTACKITEM
226 FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */
227 FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */
228 FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */
229 FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */
230 FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */
231 FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */
232 FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */
233 FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */
234 FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */
235 FFECOM_rttypeDOUBLE_, /* C's `double' type. */
236 FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */
237 FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */
238 FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */
239 FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */
243 /* Internal typedefs. */
245 typedef struct _ffecom_concat_list_ ffecomConcatList_;
247 /* Private include files. */
250 /* Internal structure definitions. */
252 struct _ffecom_concat_list_
257 ffetargetCharacterSize minlen;
258 ffetargetCharacterSize maxlen;
261 /* Static functions (internal). */
263 static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
264 static tree ffecom_widest_expr_type_ (ffebld list);
265 static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
266 tree dest_size, tree source_tree,
267 ffebld source, bool scalar_arg);
268 static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
269 tree args, tree callee_commons,
271 static tree ffecom_build_f2c_string_ (int i, const char *s);
272 static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
273 bool is_f2c_complex, tree type,
274 tree args, tree dest_tree,
275 ffebld dest, bool *dest_used,
276 tree callee_commons, bool scalar_args, tree hook);
277 static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
278 bool is_f2c_complex, tree type,
279 ffebld left, ffebld right,
280 tree dest_tree, ffebld dest,
281 bool *dest_used, tree callee_commons,
282 bool scalar_args, bool ref, tree hook);
283 static void ffecom_char_args_x_ (tree *xitem, tree *length,
284 ffebld expr, bool with_null);
285 static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
286 static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
287 static ffecomConcatList_
288 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
290 ffetargetCharacterSize max);
291 static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
292 static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
293 ffetargetCharacterSize max);
294 static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
295 ffesymbol member, tree member_type,
296 ffetargetOffset offset);
297 static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
298 static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
299 bool *dest_used, bool assignp, bool widenp);
300 static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
301 ffebld dest, bool *dest_used);
302 static tree ffecom_expr_power_integer_ (ffebld expr);
303 static void ffecom_expr_transform_ (ffebld expr);
304 static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
305 static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
307 static ffeglobal ffecom_finish_global_ (ffeglobal global);
308 static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
309 static tree ffecom_get_appended_identifier_ (char us, const char *text);
310 static tree ffecom_get_external_identifier_ (ffesymbol s);
311 static tree ffecom_get_identifier_ (const char *text);
312 static tree ffecom_gen_sfuncdef_ (ffesymbol s,
315 static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
316 static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
317 static tree ffecom_init_zero_ (tree decl);
318 static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
320 static tree ffecom_intrinsic_len_ (ffebld expr);
321 static void ffecom_let_char_ (tree dest_tree,
323 ffetargetCharacterSize dest_size,
325 static void ffecom_make_gfrt_ (ffecomGfrt ix);
326 static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
327 static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
328 static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
330 static void ffecom_push_dummy_decls_ (ffebld dumlist,
332 static void ffecom_start_progunit_ (void);
333 static ffesymbol ffecom_sym_transform_ (ffesymbol s);
334 static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
335 static void ffecom_transform_common_ (ffesymbol s);
336 static void ffecom_transform_equiv_ (ffestorag st);
337 static tree ffecom_transform_namelist_ (ffesymbol s);
338 static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
340 static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
341 tree *size, tree tree);
342 static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
343 tree dest_tree, ffebld dest,
344 bool *dest_used, tree hook);
345 static tree ffecom_type_localvar_ (ffesymbol s,
348 static tree ffecom_type_namelist_ (void);
349 static tree ffecom_type_vardesc_ (void);
350 static tree ffecom_vardesc_ (ffebld expr);
351 static tree ffecom_vardesc_array_ (ffesymbol s);
352 static tree ffecom_vardesc_dims_ (ffesymbol s);
353 static tree ffecom_convert_narrow_ (tree type, tree expr);
354 static tree ffecom_convert_widen_ (tree type, tree expr);
356 /* These are static functions that parallel those found in the C front
357 end and thus have the same names. */
359 static tree bison_rule_compstmt_ (void);
360 static void bison_rule_pushlevel_ (void);
361 static void delete_block (tree block);
362 static int duplicate_decls (tree newdecl, tree olddecl);
363 static void finish_decl (tree decl, tree init, bool is_top_level);
364 static void finish_function (int nested);
365 static const char *lang_printable_name (tree decl, int v);
366 static tree lookup_name_current_level (tree name);
367 static struct binding_level *make_binding_level (void);
368 static void pop_f_function_context (void);
369 static void push_f_function_context (void);
370 static void push_parm_decl (tree parm);
371 static tree pushdecl_top_level (tree decl);
372 static int kept_level_p (void);
373 static tree storedecls (tree decls);
374 static void store_parm_decls (int is_main_program);
375 static tree start_decl (tree decl, bool is_top_level);
376 static void start_function (tree name, tree type, int nested, int public);
377 static void ffecom_file_ (const char *name);
378 static void ffecom_close_include_ (FILE *f);
379 static int ffecom_decode_include_option_ (char *spec);
380 static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
383 /* Static objects accessed by functions in this module. */
385 static ffesymbol ffecom_primary_entry_ = NULL;
386 static ffesymbol ffecom_nested_entry_ = NULL;
387 static ffeinfoKind ffecom_primary_entry_kind_;
388 static bool ffecom_primary_entry_is_proc_;
389 static tree ffecom_outer_function_decl_;
390 static tree ffecom_previous_function_decl_;
391 static tree ffecom_which_entrypoint_decl_;
392 static tree ffecom_float_zero_ = NULL_TREE;
393 static tree ffecom_float_half_ = NULL_TREE;
394 static tree ffecom_double_zero_ = NULL_TREE;
395 static tree ffecom_double_half_ = NULL_TREE;
396 static tree ffecom_func_result_;/* For functions. */
397 static tree ffecom_func_length_;/* For CHARACTER fns. */
398 static ffebld ffecom_list_blockdata_;
399 static ffebld ffecom_list_common_;
400 static ffebld ffecom_master_arglist_;
401 static ffeinfoBasictype ffecom_master_bt_;
402 static ffeinfoKindtype ffecom_master_kt_;
403 static ffetargetCharacterSize ffecom_master_size_;
404 static int ffecom_num_fns_ = 0;
405 static int ffecom_num_entrypoints_ = 0;
406 static bool ffecom_is_altreturning_ = FALSE;
407 static tree ffecom_multi_type_node_;
408 static tree ffecom_multi_retval_;
410 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
411 static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
412 static bool ffecom_doing_entry_ = FALSE;
413 static bool ffecom_transform_only_dummies_ = FALSE;
414 static int ffecom_typesize_pointer_;
415 static int ffecom_typesize_integer1_;
417 /* Holds pointer-to-function expressions. */
419 static tree ffecom_gfrt_[FFECOM_gfrt]
422 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NULL_TREE,
423 #include "com-rt.def"
427 /* Holds the external names of the functions. */
429 static const char *const ffecom_gfrt_name_[FFECOM_gfrt]
432 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NAME,
433 #include "com-rt.def"
437 /* Whether the function returns. */
439 static bool ffecom_gfrt_volatile_[FFECOM_gfrt]
442 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) VOLATILE,
443 #include "com-rt.def"
447 /* Whether the function returns type complex. */
449 static bool ffecom_gfrt_complex_[FFECOM_gfrt]
452 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) COMPLEX,
453 #include "com-rt.def"
457 /* Whether the function is const
458 (i.e., has no side effects and only depends on its arguments). */
460 static bool ffecom_gfrt_const_[FFECOM_gfrt]
463 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) CONST,
464 #include "com-rt.def"
468 /* Type code for the function return value. */
470 static ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
473 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) TYPE,
474 #include "com-rt.def"
478 /* String of codes for the function's arguments. */
480 static const char *const ffecom_gfrt_argstring_[FFECOM_gfrt]
483 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) ARGS,
484 #include "com-rt.def"
488 /* Internal macros. */
490 /* We let tm.h override the types used here, to handle trivial differences
491 such as the choice of unsigned int or long unsigned int for size_t.
492 When machines start needing nontrivial differences in the size type,
493 it would be best to do something here to figure out automatically
494 from other information what type to use. */
497 #define SIZE_TYPE "long unsigned int"
500 #define ffecom_concat_list_count_(catlist) ((catlist).count)
501 #define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
502 #define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
503 #define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
505 #define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
506 #define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
508 /* For each binding contour we allocate a binding_level structure
509 * which records the names defined in that contour.
512 * 1) one for each function definition,
513 * where internal declarations of the parameters appear.
515 * The current meaning of a name can be found by searching the levels from
516 * the current one out to the global one.
519 /* Note that the information in the `names' component of the global contour
520 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
524 /* A chain of _DECL nodes for all variables, constants, functions,
525 and typedef types. These are in the reverse of the order supplied.
529 /* For each level (except not the global one),
530 a chain of BLOCK nodes for all the levels
531 that were entered and exited one level down. */
534 /* The BLOCK node for this level, if one has been preallocated.
535 If 0, the BLOCK is allocated (if needed) when the level is popped. */
538 /* The binding level which this one is contained in (inherits from). */
539 struct binding_level *level_chain;
541 /* 0: no ffecom_prepare_* functions called at this level yet;
542 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
543 2: ffecom_prepare_end called. */
547 #define NULL_BINDING_LEVEL (struct binding_level *) NULL
549 /* The binding level currently in effect. */
551 static struct binding_level *current_binding_level;
553 /* A chain of binding_level structures awaiting reuse. */
555 static struct binding_level *free_binding_level;
557 /* The outermost binding level, for names of file scope.
558 This is created when the compiler is started and exists
559 through the entire run. */
561 static struct binding_level *global_binding_level;
563 /* Binding level structures are initialized by copying this one. */
565 static struct binding_level clear_binding_level
567 {NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
569 /* Language-dependent contents of an identifier. */
571 struct lang_identifier
573 struct tree_identifier ignore;
574 tree global_value, local_value, label_value;
578 /* Macros for access to language-specific slots in an identifier. */
579 /* Each of these slots contains a DECL node or null. */
581 /* This represents the value which the identifier has in the
582 file-scope namespace. */
583 #define IDENTIFIER_GLOBAL_VALUE(NODE) \
584 (((struct lang_identifier *)(NODE))->global_value)
585 /* This represents the value which the identifier has in the current
587 #define IDENTIFIER_LOCAL_VALUE(NODE) \
588 (((struct lang_identifier *)(NODE))->local_value)
589 /* This represents the value which the identifier has as a label in
590 the current label scope. */
591 #define IDENTIFIER_LABEL_VALUE(NODE) \
592 (((struct lang_identifier *)(NODE))->label_value)
593 /* This is nonzero if the identifier was "made up" by g77 code. */
594 #define IDENTIFIER_INVENTED(NODE) \
595 (((struct lang_identifier *)(NODE))->invented)
597 /* In identifiers, C uses the following fields in a special way:
598 TREE_PUBLIC to record that there was a previous local extern decl.
599 TREE_USED to record that such a decl was used.
600 TREE_ADDRESSABLE to record that the address of such a decl was used. */
602 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
603 that have names. Here so we can clear out their names' definitions
604 at the end of the function. */
606 static tree named_labels;
608 /* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
610 static tree shadowed_labels;
612 /* Return the subscript expression, modified to do range-checking.
614 `array' is the array to be checked against.
615 `element' is the subscript expression to check.
616 `dim' is the dimension number (starting at 0).
617 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
621 ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
622 const char *array_name)
624 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
625 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
630 if (element == error_mark_node)
633 if (TREE_TYPE (low) != TREE_TYPE (element))
635 if (TYPE_PRECISION (TREE_TYPE (low))
636 > TYPE_PRECISION (TREE_TYPE (element)))
637 element = convert (TREE_TYPE (low), element);
640 low = convert (TREE_TYPE (element), low);
642 high = convert (TREE_TYPE (element), high);
646 element = ffecom_save_tree (element);
649 /* Special handling for substring range checks. Fortran allows the
650 end subscript < begin subscript, which means that expressions like
651 string(1:0) are valid (and yield a null string). In view of this,
652 enforce two simpler conditions:
653 1) element<=high for end-substring;
654 2) element>=low for start-substring.
655 Run-time character movement will enforce remaining conditions.
657 More complicated checks would be better, but present structure only
658 provides one index element at a time, so it is not possible to
659 enforce a check of both i and j in string(i:j). If it were, the
660 complete set of rules would read,
661 if ( ((j<i) && ((low<=i<=high) || (low<=j<=high))) ||
662 ((low<=i<=high) && (low<=j<=high)) )
668 cond = ffecom_2 (LE_EXPR, integer_type_node, element, high);
670 cond = ffecom_2 (LE_EXPR, integer_type_node, low, element);
674 /* Array reference substring range checking. */
676 cond = ffecom_2 (LE_EXPR, integer_type_node,
681 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
683 ffecom_2 (LE_EXPR, integer_type_node,
701 var = concat (array_name, "[", (dim ? "end" : "start"),
702 "-substring]", NULL);
703 len = strlen (var) + 1;
704 arg1 = build_string (len, var);
709 len = strlen (array_name) + 1;
710 arg1 = build_string (len, array_name);
714 var = xmalloc (strlen (array_name) + 40);
715 sprintf (var, "%s[subscript-%d-of-%d]",
717 dim + 1, total_dims);
718 len = strlen (var) + 1;
719 arg1 = build_string (len, var);
725 = build_type_variant (build_array_type (char_type_node,
729 build_int_2 (len, 0))),
731 TREE_CONSTANT (arg1) = 1;
732 TREE_STATIC (arg1) = 1;
733 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
736 /* s_rnge adds one to the element to print it, so bias against
737 that -- want to print a faithful *subscript* value. */
738 arg2 = convert (ffecom_f2c_ftnint_type_node,
739 ffecom_2 (MINUS_EXPR,
742 convert (TREE_TYPE (element),
745 proc = concat (input_filename, "/",
746 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
748 len = strlen (proc) + 1;
749 arg3 = build_string (len, proc);
754 = build_type_variant (build_array_type (char_type_node,
758 build_int_2 (len, 0))),
760 TREE_CONSTANT (arg3) = 1;
761 TREE_STATIC (arg3) = 1;
762 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
765 arg4 = convert (ffecom_f2c_ftnint_type_node,
766 build_int_2 (lineno, 0));
768 arg1 = build_tree_list (NULL_TREE, arg1);
769 arg2 = build_tree_list (NULL_TREE, arg2);
770 arg3 = build_tree_list (NULL_TREE, arg3);
771 arg4 = build_tree_list (NULL_TREE, arg4);
772 TREE_CHAIN (arg3) = arg4;
773 TREE_CHAIN (arg2) = arg3;
774 TREE_CHAIN (arg1) = arg2;
778 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
780 TREE_SIDE_EFFECTS (die) = 1;
782 element = ffecom_3 (COND_EXPR,
791 /* Return the computed element of an array reference.
793 `item' is NULL_TREE, or the transformed pointer to the array.
794 `expr' is the original opARRAYREF expression, which is transformed
795 if `item' is NULL_TREE.
796 `want_ptr' is non-zero if a pointer to the element, instead of
797 the element itself, is to be returned. */
800 ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
802 ffebld dims[FFECOM_dimensionsMAX];
805 int flatten = ffe_is_flatten_arrays ();
811 const char *array_name;
815 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
816 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
818 array_name = "[expr?]";
820 /* Build up ARRAY_REFs in reverse order (since we're column major
821 here in Fortran land). */
823 for (i = 0, list = ffebld_right (expr);
825 ++i, list = ffebld_trail (list))
827 dims[i] = ffebld_head (list);
828 type = ffeinfo_type (ffebld_basictype (dims[i]),
829 ffebld_kindtype (dims[i]));
831 && ffecom_typesize_pointer_ > ffecom_typesize_integer1_
832 && ffetype_size (type) > ffecom_typesize_integer1_)
833 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
834 pointers and 32-bit integers. Do the full 64-bit pointer
835 arithmetic, for codes using arrays for nonstandard heap-like
842 need_ptr = want_ptr || flatten;
847 item = ffecom_ptr_to_expr (ffebld_left (expr));
849 item = ffecom_expr (ffebld_left (expr));
851 if (item == error_mark_node)
854 if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
855 && ! mark_addressable (item))
856 return error_mark_node;
859 if (item == error_mark_node)
866 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
868 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
870 min = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
871 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
872 if (flag_bounds_check)
873 element = ffecom_subscript_check_ (array, element, i, total_dims,
875 if (element == error_mark_node)
878 /* Widen integral arithmetic as desired while preserving
880 tree_type = TREE_TYPE (element);
881 tree_type_x = tree_type;
883 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
884 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
885 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
887 if (TREE_TYPE (min) != tree_type_x)
888 min = convert (tree_type_x, min);
889 if (TREE_TYPE (element) != tree_type_x)
890 element = convert (tree_type_x, element);
892 item = ffecom_2 (PLUS_EXPR,
893 build_pointer_type (TREE_TYPE (array)),
895 size_binop (MULT_EXPR,
896 size_in_bytes (TREE_TYPE (array)),
898 fold (build (MINUS_EXPR,
904 item = ffecom_1 (INDIRECT_REF,
905 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
915 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
917 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
918 if (flag_bounds_check)
919 element = ffecom_subscript_check_ (array, element, i, total_dims,
921 if (element == error_mark_node)
924 /* Widen integral arithmetic as desired while preserving
926 tree_type = TREE_TYPE (element);
927 tree_type_x = tree_type;
929 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
930 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
931 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
933 element = convert (tree_type_x, element);
935 item = ffecom_2 (ARRAY_REF,
936 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
945 /* This is like gcc's stabilize_reference -- in fact, most of the code
946 comes from that -- but it handles the situation where the reference
947 is going to have its subparts picked at, and it shouldn't change
948 (or trigger extra invocations of functions in the subtrees) due to
949 this. save_expr is a bit overzealous, because we don't need the
950 entire thing calculated and saved like a temp. So, for DECLs, no
951 change is needed, because these are stable aggregates, and ARRAY_REF
952 and such might well be stable too, but for things like calculations,
953 we do need to calculate a snapshot of a value before picking at it. */
956 ffecom_stabilize_aggregate_ (tree ref)
959 enum tree_code code = TREE_CODE (ref);
966 /* No action is needed in this case. */
976 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
980 result = build_nt (INDIRECT_REF,
981 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
985 result = build_nt (COMPONENT_REF,
986 stabilize_reference (TREE_OPERAND (ref, 0)),
987 TREE_OPERAND (ref, 1));
991 result = build_nt (BIT_FIELD_REF,
992 stabilize_reference (TREE_OPERAND (ref, 0)),
993 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
994 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
998 result = build_nt (ARRAY_REF,
999 stabilize_reference (TREE_OPERAND (ref, 0)),
1000 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1004 result = build_nt (COMPOUND_EXPR,
1005 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1006 stabilize_reference (TREE_OPERAND (ref, 1)));
1014 return save_expr (ref);
1017 return error_mark_node;
1020 TREE_TYPE (result) = TREE_TYPE (ref);
1021 TREE_READONLY (result) = TREE_READONLY (ref);
1022 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1023 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
1028 /* A rip-off of gcc's convert.c convert_to_complex function,
1029 reworked to handle complex implemented as C structures
1030 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1033 ffecom_convert_to_complex_ (tree type, tree expr)
1035 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1038 assert (TREE_CODE (type) == RECORD_TYPE);
1040 subtype = TREE_TYPE (TYPE_FIELDS (type));
1042 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1044 expr = convert (subtype, expr);
1045 return ffecom_2 (COMPLEX_EXPR, type, expr,
1046 convert (subtype, integer_zero_node));
1049 if (form == RECORD_TYPE)
1051 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1052 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1056 expr = save_expr (expr);
1057 return ffecom_2 (COMPLEX_EXPR,
1060 ffecom_1 (REALPART_EXPR,
1061 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1064 ffecom_1 (IMAGPART_EXPR,
1065 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1070 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1071 error ("pointer value used where a complex was expected");
1073 error ("aggregate value used where a complex was expected");
1075 return ffecom_2 (COMPLEX_EXPR, type,
1076 convert (subtype, integer_zero_node),
1077 convert (subtype, integer_zero_node));
1080 /* Like gcc's convert(), but crashes if widening might happen. */
1083 ffecom_convert_narrow_ (type, expr)
1086 register tree e = expr;
1087 register enum tree_code code = TREE_CODE (type);
1089 if (type == TREE_TYPE (e)
1090 || TREE_CODE (e) == ERROR_MARK)
1092 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1093 return fold (build1 (NOP_EXPR, type, e));
1094 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1095 || code == ERROR_MARK)
1096 return error_mark_node;
1097 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1099 assert ("void value not ignored as it ought to be" == NULL);
1100 return error_mark_node;
1102 assert (code != VOID_TYPE);
1103 if ((code != RECORD_TYPE)
1104 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1105 assert ("converting COMPLEX to REAL" == NULL);
1106 assert (code != ENUMERAL_TYPE);
1107 if (code == INTEGER_TYPE)
1109 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1110 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
1111 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1112 && (TYPE_PRECISION (type)
1113 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1114 return fold (convert_to_integer (type, e));
1116 if (code == POINTER_TYPE)
1118 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1119 return fold (convert_to_pointer (type, e));
1121 if (code == REAL_TYPE)
1123 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1124 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
1125 return fold (convert_to_real (type, e));
1127 if (code == COMPLEX_TYPE)
1129 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1130 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1131 return fold (convert_to_complex (type, e));
1133 if (code == RECORD_TYPE)
1135 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1136 /* Check that at least the first field name agrees. */
1137 assert (DECL_NAME (TYPE_FIELDS (type))
1138 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1139 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1140 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1141 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1142 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1144 return fold (ffecom_convert_to_complex_ (type, e));
1147 assert ("conversion to non-scalar type requested" == NULL);
1148 return error_mark_node;
1151 /* Like gcc's convert(), but crashes if narrowing might happen. */
1154 ffecom_convert_widen_ (type, expr)
1157 register tree e = expr;
1158 register enum tree_code code = TREE_CODE (type);
1160 if (type == TREE_TYPE (e)
1161 || TREE_CODE (e) == ERROR_MARK)
1163 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1164 return fold (build1 (NOP_EXPR, type, e));
1165 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1166 || code == ERROR_MARK)
1167 return error_mark_node;
1168 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1170 assert ("void value not ignored as it ought to be" == NULL);
1171 return error_mark_node;
1173 assert (code != VOID_TYPE);
1174 if ((code != RECORD_TYPE)
1175 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1176 assert ("narrowing COMPLEX to REAL" == NULL);
1177 assert (code != ENUMERAL_TYPE);
1178 if (code == INTEGER_TYPE)
1180 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1181 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1182 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1183 && (TYPE_PRECISION (type)
1184 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1185 return fold (convert_to_integer (type, e));
1187 if (code == POINTER_TYPE)
1189 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1190 return fold (convert_to_pointer (type, e));
1192 if (code == REAL_TYPE)
1194 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1195 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1196 return fold (convert_to_real (type, e));
1198 if (code == COMPLEX_TYPE)
1200 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1201 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1202 return fold (convert_to_complex (type, e));
1204 if (code == RECORD_TYPE)
1206 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1207 /* Check that at least the first field name agrees. */
1208 assert (DECL_NAME (TYPE_FIELDS (type))
1209 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1210 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1211 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1212 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1213 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1215 return fold (ffecom_convert_to_complex_ (type, e));
1218 assert ("conversion to non-scalar type requested" == NULL);
1219 return error_mark_node;
1222 /* Handles making a COMPLEX type, either the standard
1223 (but buggy?) gbe way, or the safer (but less elegant?)
1227 ffecom_make_complex_type_ (tree subtype)
1233 if (ffe_is_emulate_complex ())
1235 type = make_node (RECORD_TYPE);
1236 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1237 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1238 TYPE_FIELDS (type) = realfield;
1243 type = make_node (COMPLEX_TYPE);
1244 TREE_TYPE (type) = subtype;
1251 /* Chooses either the gbe or the f2c way to build a
1252 complex constant. */
1255 ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1259 if (ffe_is_emulate_complex ())
1261 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1262 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1263 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
1267 bothparts = build_complex (type, realpart, imagpart);
1274 ffecom_arglist_expr_ (const char *c, ffebld expr)
1277 tree *plist = &list;
1278 tree trail = NULL_TREE; /* Append char length args here. */
1279 tree *ptrail = &trail;
1284 tree wanted = NULL_TREE;
1285 static char zed[] = "0";
1290 while (expr != NULL)
1313 wanted = ffecom_f2c_complex_type_node;
1317 wanted = ffecom_f2c_doublereal_type_node;
1321 wanted = ffecom_f2c_doublecomplex_type_node;
1325 wanted = ffecom_f2c_real_type_node;
1329 wanted = ffecom_f2c_integer_type_node;
1333 wanted = ffecom_f2c_longint_type_node;
1337 assert ("bad argstring code" == NULL);
1343 exprh = ffebld_head (expr);
1347 if ((wanted == NULL_TREE)
1350 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1351 [ffeinfo_kindtype (ffebld_info (exprh))])
1352 == TYPE_MODE (wanted))))
1354 = build_tree_list (NULL_TREE,
1355 ffecom_arg_ptr_to_expr (exprh,
1359 item = ffecom_arg_expr (exprh, &length);
1360 item = ffecom_convert_widen_ (wanted, item);
1363 item = ffecom_1 (ADDR_EXPR,
1364 build_pointer_type (TREE_TYPE (item)),
1368 = build_tree_list (NULL_TREE,
1372 plist = &TREE_CHAIN (*plist);
1373 expr = ffebld_trail (expr);
1374 if (length != NULL_TREE)
1376 *ptrail = build_tree_list (NULL_TREE, length);
1377 ptrail = &TREE_CHAIN (*ptrail);
1381 /* We've run out of args in the call; if the implementation expects
1382 more, supply null pointers for them, which the implementation can
1383 check to see if an arg was omitted. */
1385 while (*c != '\0' && *c != '0')
1390 assert ("missing arg to run-time routine!" == NULL);
1405 assert ("bad arg string code" == NULL);
1409 = build_tree_list (NULL_TREE,
1411 plist = &TREE_CHAIN (*plist);
1420 ffecom_widest_expr_type_ (ffebld list)
1423 ffebld widest = NULL;
1425 ffetype widest_type = NULL;
1428 for (; list != NULL; list = ffebld_trail (list))
1430 item = ffebld_head (list);
1433 if ((widest != NULL)
1434 && (ffeinfo_basictype (ffebld_info (item))
1435 != ffeinfo_basictype (ffebld_info (widest))))
1437 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1438 ffeinfo_kindtype (ffebld_info (item)));
1439 if ((widest == FFEINFO_kindtypeNONE)
1440 || (ffetype_size (type)
1441 > ffetype_size (widest_type)))
1448 assert (widest != NULL);
1449 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1450 [ffeinfo_kindtype (ffebld_info (widest))];
1451 assert (t != NULL_TREE);
1455 /* Check whether a partial overlap between two expressions is possible.
1457 Can *starting* to write a portion of expr1 change the value
1458 computed (perhaps already, *partially*) by expr2?
1460 Currently, this is a concern only for a COMPLEX expr1. But if it
1461 isn't in COMMON or local EQUIVALENCE, since we don't support
1462 aliasing of arguments, it isn't a concern. */
1465 ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2 ATTRIBUTE_UNUSED)
1470 switch (ffebld_op (expr1))
1472 case FFEBLD_opSYMTER:
1473 sym = ffebld_symter (expr1);
1476 case FFEBLD_opARRAYREF:
1477 if (ffebld_op (ffebld_left (expr1)) != FFEBLD_opSYMTER)
1479 sym = ffebld_symter (ffebld_left (expr1));
1486 if (ffesymbol_where (sym) != FFEINFO_whereCOMMON
1487 && (ffesymbol_where (sym) != FFEINFO_whereLOCAL
1488 || ! (st = ffesymbol_storage (sym))
1489 || ! ffestorag_parent (st)))
1492 /* It's in COMMON or local EQUIVALENCE. */
1497 /* Check whether dest and source might overlap. ffebld versions of these
1498 might or might not be passed, will be NULL if not.
1500 The test is really whether source_tree is modifiable and, if modified,
1501 might overlap destination such that the value(s) in the destination might
1502 change before it is finally modified. dest_* are the canonized
1503 destination itself. */
1506 ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1507 tree source_tree, ffebld source UNUSED,
1515 if (source_tree == NULL_TREE)
1518 switch (TREE_CODE (source_tree))
1521 case IDENTIFIER_NODE:
1532 case TRUNC_DIV_EXPR:
1534 case FLOOR_DIV_EXPR:
1535 case ROUND_DIV_EXPR:
1536 case TRUNC_MOD_EXPR:
1538 case FLOOR_MOD_EXPR:
1539 case ROUND_MOD_EXPR:
1541 case EXACT_DIV_EXPR:
1542 case FIX_TRUNC_EXPR:
1544 case FIX_FLOOR_EXPR:
1545 case FIX_ROUND_EXPR:
1559 case BIT_ANDTC_EXPR:
1561 case TRUTH_ANDIF_EXPR:
1562 case TRUTH_ORIF_EXPR:
1563 case TRUTH_AND_EXPR:
1565 case TRUTH_XOR_EXPR:
1566 case TRUTH_NOT_EXPR:
1582 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1583 TREE_OPERAND (source_tree, 1), NULL,
1587 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1588 TREE_OPERAND (source_tree, 0), NULL,
1593 case NON_LVALUE_EXPR:
1595 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1598 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1600 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1605 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1606 TREE_OPERAND (source_tree, 1), NULL,
1608 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1609 TREE_OPERAND (source_tree, 2), NULL,
1614 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1616 TREE_OPERAND (source_tree, 0));
1620 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1623 source_decl = source_tree;
1624 source_offset = bitsize_zero_node;
1625 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1629 case REFERENCE_EXPR:
1630 case PREDECREMENT_EXPR:
1631 case PREINCREMENT_EXPR:
1632 case POSTDECREMENT_EXPR:
1633 case POSTINCREMENT_EXPR:
1641 /* Come here when source_decl, source_offset, and source_size filled
1642 in appropriately. */
1644 if (source_decl == NULL_TREE)
1645 return FALSE; /* No decl involved, so no overlap. */
1647 if (source_decl != dest_decl)
1648 return FALSE; /* Different decl, no overlap. */
1650 if (TREE_CODE (dest_size) == ERROR_MARK)
1651 return TRUE; /* Assignment into entire assumed-size
1652 array? Shouldn't happen.... */
1654 t = ffecom_2 (LE_EXPR, integer_type_node,
1655 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1657 convert (TREE_TYPE (dest_offset),
1659 convert (TREE_TYPE (dest_offset),
1662 if (integer_onep (t))
1663 return FALSE; /* Destination precedes source. */
1666 || (source_size == NULL_TREE)
1667 || (TREE_CODE (source_size) == ERROR_MARK)
1668 || integer_zerop (source_size))
1669 return TRUE; /* No way to tell if dest follows source. */
1671 t = ffecom_2 (LE_EXPR, integer_type_node,
1672 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1674 convert (TREE_TYPE (source_offset),
1676 convert (TREE_TYPE (source_offset),
1679 if (integer_onep (t))
1680 return FALSE; /* Destination follows source. */
1682 return TRUE; /* Destination and source overlap. */
1685 /* Check whether dest might overlap any of a list of arguments or is
1686 in a COMMON area the callee might know about (and thus modify). */
1689 ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
1690 tree args, tree callee_commons,
1698 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1701 if (dest_decl == NULL_TREE)
1702 return FALSE; /* Seems unlikely! */
1704 /* If the decl cannot be determined reliably, or if its in COMMON
1705 and the callee isn't known to not futz with COMMON via other
1706 means, overlap might happen. */
1708 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1709 || ((callee_commons != NULL_TREE)
1710 && TREE_PUBLIC (dest_decl)))
1713 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1715 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1716 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1717 arg, NULL, scalar_args))
1724 /* Build a string for a variable name as used by NAMELIST. This means that
1725 if we're using the f2c library, we build an uppercase string, since
1729 ffecom_build_f2c_string_ (int i, const char *s)
1731 if (!ffe_is_f2c_library ())
1732 return build_string (i, s);
1741 if (((size_t) i) > ARRAY_SIZE (space))
1742 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1746 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
1750 t = build_string (i, tmp);
1752 if (((size_t) i) > ARRAY_SIZE (space))
1753 malloc_kill_ks (malloc_pool_image (), tmp, i);
1759 /* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1760 type to just get whatever the function returns), handling the
1761 f2c value-returning convention, if required, by prepending
1762 to the arglist a pointer to a temporary to receive the return value. */
1765 ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1766 tree type, tree args, tree dest_tree,
1767 ffebld dest, bool *dest_used, tree callee_commons,
1768 bool scalar_args, tree hook)
1773 if (dest_used != NULL)
1778 if ((dest_used == NULL)
1780 || (ffeinfo_basictype (ffebld_info (dest))
1781 != FFEINFO_basictypeCOMPLEX)
1782 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1783 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1784 || ffecom_args_overlapping_ (dest_tree, dest, args,
1789 tempvar = ffecom_make_tempvar (ffecom_tree_type
1790 [FFEINFO_basictypeCOMPLEX][kt],
1791 FFETARGET_charactersizeNONE,
1801 tempvar = dest_tree;
1806 = build_tree_list (NULL_TREE,
1807 ffecom_1 (ADDR_EXPR,
1808 build_pointer_type (TREE_TYPE (tempvar)),
1810 TREE_CHAIN (item) = args;
1812 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1815 if (tempvar != dest_tree)
1816 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1819 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1822 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1823 item = ffecom_convert_narrow_ (type, item);
1828 /* Given two arguments, transform them and make a call to the given
1829 function via ffecom_call_. */
1832 ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1833 tree type, ffebld left, ffebld right,
1834 tree dest_tree, ffebld dest, bool *dest_used,
1835 tree callee_commons, bool scalar_args, bool ref, tree hook)
1844 /* Pass arguments by reference. */
1845 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1846 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
1850 /* Pass arguments by value. */
1851 left_tree = ffecom_arg_expr (left, &left_length);
1852 right_tree = ffecom_arg_expr (right, &right_length);
1856 left_tree = build_tree_list (NULL_TREE, left_tree);
1857 right_tree = build_tree_list (NULL_TREE, right_tree);
1858 TREE_CHAIN (left_tree) = right_tree;
1860 if (left_length != NULL_TREE)
1862 left_length = build_tree_list (NULL_TREE, left_length);
1863 TREE_CHAIN (right_tree) = left_length;
1866 if (right_length != NULL_TREE)
1868 right_length = build_tree_list (NULL_TREE, right_length);
1869 if (left_length != NULL_TREE)
1870 TREE_CHAIN (left_length) = right_length;
1872 TREE_CHAIN (right_tree) = right_length;
1875 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1876 dest_tree, dest, dest_used, callee_commons,
1880 /* Return ptr/length args for char subexpression
1882 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1883 subexpressions by constructing the appropriate trees for the ptr-to-
1884 character-text and length-of-character-text arguments in a calling
1887 Note that if with_null is TRUE, and the expression is an opCONTER,
1888 a null byte is appended to the string. */
1891 ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
1895 ffetargetCharacter1 val;
1896 ffetargetCharacterSize newlen;
1898 switch (ffebld_op (expr))
1900 case FFEBLD_opCONTER:
1901 val = ffebld_constant_character1 (ffebld_conter (expr));
1902 newlen = ffetarget_length_character1 (val);
1905 /* Begin FFETARGET-NULL-KLUDGE. */
1909 *length = build_int_2 (newlen, 0);
1910 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1911 high = build_int_2 (newlen, 0);
1912 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
1913 item = build_string (newlen,
1914 ffetarget_text_character1 (val));
1915 /* End FFETARGET-NULL-KLUDGE. */
1917 = build_type_variant
1921 (ffecom_f2c_ftnlen_type_node,
1922 ffecom_f2c_ftnlen_one_node,
1925 TREE_CONSTANT (item) = 1;
1926 TREE_STATIC (item) = 1;
1927 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
1931 case FFEBLD_opSYMTER:
1933 ffesymbol s = ffebld_symter (expr);
1935 item = ffesymbol_hook (s).decl_tree;
1936 if (item == NULL_TREE)
1938 s = ffecom_sym_transform_ (s);
1939 item = ffesymbol_hook (s).decl_tree;
1941 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
1943 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
1944 *length = ffesymbol_hook (s).length_tree;
1947 *length = build_int_2 (ffesymbol_size (s), 0);
1948 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1951 else if (item == error_mark_node)
1952 *length = error_mark_node;
1954 /* FFEINFO_kindFUNCTION. */
1955 *length = NULL_TREE;
1956 if (!ffesymbol_hook (s).addr
1957 && (item != error_mark_node))
1958 item = ffecom_1 (ADDR_EXPR,
1959 build_pointer_type (TREE_TYPE (item)),
1964 case FFEBLD_opARRAYREF:
1966 ffecom_char_args_ (&item, length, ffebld_left (expr));
1968 if (item == error_mark_node || *length == error_mark_node)
1970 item = *length = error_mark_node;
1974 item = ffecom_arrayref_ (item, expr, 1);
1978 case FFEBLD_opSUBSTR:
1982 ffebld thing = ffebld_right (expr);
1985 const char *char_name;
1989 assert (ffebld_op (thing) == FFEBLD_opITEM);
1990 start = ffebld_head (thing);
1991 thing = ffebld_trail (thing);
1992 assert (ffebld_trail (thing) == NULL);
1993 end = ffebld_head (thing);
1995 /* Determine name for pretty-printing range-check errors. */
1996 for (left_symter = ffebld_left (expr);
1997 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
1998 left_symter = ffebld_left (left_symter))
2000 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2001 char_name = ffesymbol_text (ffebld_symter (left_symter));
2003 char_name = "[expr?]";
2005 ffecom_char_args_ (&item, length, ffebld_left (expr));
2007 if (item == error_mark_node || *length == error_mark_node)
2009 item = *length = error_mark_node;
2013 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2015 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2023 end_tree = ffecom_expr (end);
2024 if (flag_bounds_check)
2025 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2027 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2030 if (end_tree == error_mark_node)
2032 item = *length = error_mark_node;
2041 start_tree = ffecom_expr (start);
2042 if (flag_bounds_check)
2043 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2045 start_tree = convert (ffecom_f2c_ftnlen_type_node,
2048 if (start_tree == error_mark_node)
2050 item = *length = error_mark_node;
2054 start_tree = ffecom_save_tree (start_tree);
2056 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2058 ffecom_2 (MINUS_EXPR,
2059 TREE_TYPE (start_tree),
2061 ffecom_f2c_ftnlen_one_node));
2065 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2066 ffecom_f2c_ftnlen_one_node,
2067 ffecom_2 (MINUS_EXPR,
2068 ffecom_f2c_ftnlen_type_node,
2074 end_tree = ffecom_expr (end);
2075 if (flag_bounds_check)
2076 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2078 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2081 if (end_tree == error_mark_node)
2083 item = *length = error_mark_node;
2087 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2088 ffecom_f2c_ftnlen_one_node,
2089 ffecom_2 (MINUS_EXPR,
2090 ffecom_f2c_ftnlen_type_node,
2091 end_tree, start_tree));
2097 case FFEBLD_opFUNCREF:
2099 ffesymbol s = ffebld_symter (ffebld_left (expr));
2102 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2105 if (size == FFETARGET_charactersizeNONE)
2106 /* ~~Kludge alert! This should someday be fixed. */
2109 *length = build_int_2 (size, 0);
2110 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2112 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2113 == FFEINFO_whereINTRINSIC)
2117 /* Invocation of an intrinsic returning CHARACTER*1. */
2118 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2122 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2123 assert (ix != FFECOM_gfrt);
2124 item = ffecom_gfrt_tree_ (ix);
2129 item = ffesymbol_hook (s).decl_tree;
2130 if (item == NULL_TREE)
2132 s = ffecom_sym_transform_ (s);
2133 item = ffesymbol_hook (s).decl_tree;
2135 if (item == error_mark_node)
2137 item = *length = error_mark_node;
2141 if (!ffesymbol_hook (s).addr)
2142 item = ffecom_1_fn (item);
2146 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
2148 tempvar = ffebld_nonter_hook (expr);
2151 tempvar = ffecom_1 (ADDR_EXPR,
2152 build_pointer_type (TREE_TYPE (tempvar)),
2155 args = build_tree_list (NULL_TREE, tempvar);
2157 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */
2158 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
2161 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
2162 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
2164 TREE_CHAIN (TREE_CHAIN (args))
2165 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
2166 ffebld_right (expr));
2170 TREE_CHAIN (TREE_CHAIN (args))
2171 = ffecom_list_ptr_to_expr (ffebld_right (expr));
2175 item = ffecom_3s (CALL_EXPR,
2176 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
2177 item, args, NULL_TREE);
2178 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
2183 case FFEBLD_opCONVERT:
2185 ffecom_char_args_ (&item, length, ffebld_left (expr));
2187 if (item == error_mark_node || *length == error_mark_node)
2189 item = *length = error_mark_node;
2193 if ((ffebld_size_known (ffebld_left (expr))
2194 == FFETARGET_charactersizeNONE)
2195 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
2196 { /* Possible blank-padding needed, copy into
2203 tempvar = ffecom_make_tempvar (char_type_node,
2204 ffebld_size (expr), -1);
2206 tempvar = ffebld_nonter_hook (expr);
2209 tempvar = ffecom_1 (ADDR_EXPR,
2210 build_pointer_type (TREE_TYPE (tempvar)),
2213 newlen = build_int_2 (ffebld_size (expr), 0);
2214 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2216 args = build_tree_list (NULL_TREE, tempvar);
2217 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2218 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2219 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2220 = build_tree_list (NULL_TREE, *length);
2222 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
2223 TREE_SIDE_EFFECTS (item) = 1;
2224 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2229 { /* Just truncate the length. */
2230 *length = build_int_2 (ffebld_size (expr), 0);
2231 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2236 assert ("bad op for single char arg expr" == NULL);
2244 /* Check the size of the type to be sure it doesn't overflow the
2245 "portable" capacities of the compiler back end. `dummy' types
2246 can generally overflow the normal sizes as long as the computations
2247 themselves don't overflow. A particular target of the back end
2248 must still enforce its size requirements, though, and the back
2249 end takes care of this in stor-layout.c. */
2252 ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2254 if (TREE_CODE (type) == ERROR_MARK)
2257 if (TYPE_SIZE (type) == NULL_TREE)
2260 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2263 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
2264 || (!dummy && TREE_OVERFLOW (TYPE_SIZE (type))))
2266 ffebad_start (FFEBAD_ARRAY_LARGE);
2267 ffebad_string (ffesymbol_text (s));
2268 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2271 return error_mark_node;
2277 /* Builds a length argument (PARM_DECL). Also wraps type in an array type
2278 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2279 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2282 ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2284 ffetargetCharacterSize sz = ffesymbol_size (s);
2289 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2290 tlen = NULL_TREE; /* A statement function, no length passed. */
2293 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2294 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
2295 ffesymbol_text (s));
2297 tlen = ffecom_get_invented_identifier ("__g77_%s", "length");
2298 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
2299 DECL_ARTIFICIAL (tlen) = 1;
2302 if (sz == FFETARGET_charactersizeNONE)
2304 assert (tlen != NULL_TREE);
2305 highval = variable_size (tlen);
2309 highval = build_int_2 (sz, 0);
2310 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2313 type = build_array_type (type,
2314 build_range_type (ffecom_f2c_ftnlen_type_node,
2315 ffecom_f2c_ftnlen_one_node,
2322 /* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2324 ffecomConcatList_ catlist;
2325 ffebld expr; // expr of CHARACTER basictype.
2326 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2327 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2329 Scans expr for character subexpressions, updates and returns catlist
2332 static ffecomConcatList_
2333 ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2334 ffetargetCharacterSize max)
2336 ffetargetCharacterSize sz;
2343 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2344 return catlist; /* Don't append any more items. */
2346 switch (ffebld_op (expr))
2348 case FFEBLD_opCONTER:
2349 case FFEBLD_opSYMTER:
2350 case FFEBLD_opARRAYREF:
2351 case FFEBLD_opFUNCREF:
2352 case FFEBLD_opSUBSTR:
2353 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2354 if they don't need to preserve it. */
2355 if (catlist.count == catlist.max)
2356 { /* Make a (larger) list. */
2360 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2361 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2362 newmax * sizeof (newx[0]));
2363 if (catlist.max != 0)
2365 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2366 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2367 catlist.max * sizeof (newx[0]));
2369 catlist.max = newmax;
2370 catlist.exprs = newx;
2372 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2373 catlist.minlen += sz;
2375 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2376 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2377 catlist.maxlen = sz;
2379 catlist.maxlen += sz;
2380 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2381 { /* This item overlaps (or is beyond) the end
2382 of the destination. */
2383 switch (ffebld_op (expr))
2385 case FFEBLD_opCONTER:
2386 case FFEBLD_opSYMTER:
2387 case FFEBLD_opARRAYREF:
2388 case FFEBLD_opFUNCREF:
2389 case FFEBLD_opSUBSTR:
2390 /* ~~Do useful truncations here. */
2394 assert ("op changed or inconsistent switches!" == NULL);
2398 catlist.exprs[catlist.count++] = expr;
2401 case FFEBLD_opPAREN:
2402 expr = ffebld_left (expr);
2403 goto recurse; /* :::::::::::::::::::: */
2405 case FFEBLD_opCONCATENATE:
2406 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2407 expr = ffebld_right (expr);
2408 goto recurse; /* :::::::::::::::::::: */
2410 #if 0 /* Breaks passing small actual arg to larger
2411 dummy arg of sfunc */
2412 case FFEBLD_opCONVERT:
2413 expr = ffebld_left (expr);
2415 ffetargetCharacterSize cmax;
2417 cmax = catlist.len + ffebld_size_known (expr);
2419 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2422 goto recurse; /* :::::::::::::::::::: */
2429 assert ("bad op in _gather_" == NULL);
2434 /* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2436 ffecomConcatList_ catlist;
2437 ffecom_concat_list_kill_(catlist);
2439 Anything allocated within the list info is deallocated. */
2442 ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2444 if (catlist.max != 0)
2445 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2446 catlist.max * sizeof (catlist.exprs[0]));
2449 /* Make list of concatenated string exprs.
2451 Returns a flattened list of concatenated subexpressions given a
2452 tree of such expressions. */
2454 static ffecomConcatList_
2455 ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2457 ffecomConcatList_ catlist;
2459 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2460 return ffecom_concat_list_gather_ (catlist, expr, max);
2463 /* Provide some kind of useful info on member of aggregate area,
2464 since current g77/gcc technology does not provide debug info
2465 on these members. */
2468 ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
2469 tree member_type UNUSED, ffetargetOffset offset)
2479 for (type_id = member_type;
2480 TREE_CODE (type_id) != IDENTIFIER_NODE;
2483 switch (TREE_CODE (type_id))
2487 type_id = TYPE_NAME (type_id);
2492 type_id = TREE_TYPE (type_id);
2496 assert ("no IDENTIFIER_NODE for type!" == NULL);
2497 type_id = error_mark_node;
2503 if (ffecom_transform_only_dummies_
2504 || !ffe_is_debug_kludge ())
2505 return; /* Can't do this yet, maybe later. */
2508 + strlen (aggr_type)
2509 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2511 + IDENTIFIER_LENGTH (type_id);
2514 if (((size_t) len) >= ARRAY_SIZE (space))
2515 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2519 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2521 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2524 value = build_string (len, buff);
2526 = build_type_variant (build_array_type (char_type_node,
2530 build_int_2 (strlen (buff), 0))),
2532 decl = build_decl (VAR_DECL,
2533 ffecom_get_identifier_ (ffesymbol_text (member)),
2535 TREE_CONSTANT (decl) = 1;
2536 TREE_STATIC (decl) = 1;
2537 DECL_INITIAL (decl) = error_mark_node;
2538 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2539 decl = start_decl (decl, FALSE);
2540 finish_decl (decl, value, FALSE);
2542 if (buff != &space[0])
2543 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2546 /* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2548 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2549 int i; // entry# for this entrypoint (used by master fn)
2550 ffecom_do_entrypoint_(s,i);
2552 Makes a public entry point that calls our private master fn (already
2556 ffecom_do_entry_ (ffesymbol fn, int entrynum)
2559 tree type; /* Type of function. */
2560 tree multi_retval; /* Var holding return value (union). */
2561 tree result; /* Var holding result. */
2562 ffeinfoBasictype bt;
2566 bool charfunc; /* All entry points return same type
2568 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2569 bool multi; /* Master fn has multiple return types. */
2570 bool altreturning = FALSE; /* This entry point has alternate returns. */
2571 int old_lineno = lineno;
2572 const char *old_input_filename = input_filename;
2574 input_filename = ffesymbol_where_filename (fn);
2575 lineno = ffesymbol_where_filelinenum (fn);
2577 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2579 switch (ffecom_primary_entry_kind_)
2581 case FFEINFO_kindFUNCTION:
2583 /* Determine actual return type for function. */
2585 gt = FFEGLOBAL_typeFUNC;
2586 bt = ffesymbol_basictype (fn);
2587 kt = ffesymbol_kindtype (fn);
2588 if (bt == FFEINFO_basictypeNONE)
2590 ffeimplic_establish_symbol (fn);
2591 if (ffesymbol_funcresult (fn) != NULL)
2592 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2593 bt = ffesymbol_basictype (fn);
2594 kt = ffesymbol_kindtype (fn);
2597 if (bt == FFEINFO_basictypeCHARACTER)
2598 charfunc = TRUE, cmplxfunc = FALSE;
2599 else if ((bt == FFEINFO_basictypeCOMPLEX)
2600 && ffesymbol_is_f2c (fn))
2601 charfunc = FALSE, cmplxfunc = TRUE;
2603 charfunc = cmplxfunc = FALSE;
2606 type = ffecom_tree_fun_type_void;
2607 else if (ffesymbol_is_f2c (fn))
2608 type = ffecom_tree_fun_type[bt][kt];
2610 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2612 if ((type == NULL_TREE)
2613 || (TREE_TYPE (type) == NULL_TREE))
2614 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2616 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2619 case FFEINFO_kindSUBROUTINE:
2620 gt = FFEGLOBAL_typeSUBR;
2621 bt = FFEINFO_basictypeNONE;
2622 kt = FFEINFO_kindtypeNONE;
2623 if (ffecom_is_altreturning_)
2624 { /* Am _I_ altreturning? */
2625 for (item = ffesymbol_dummyargs (fn);
2627 item = ffebld_trail (item))
2629 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2631 altreturning = TRUE;
2636 type = ffecom_tree_subr_type;
2638 type = ffecom_tree_fun_type_void;
2641 type = ffecom_tree_fun_type_void;
2648 assert ("say what??" == NULL);
2650 case FFEINFO_kindANY:
2651 gt = FFEGLOBAL_typeANY;
2652 bt = FFEINFO_basictypeNONE;
2653 kt = FFEINFO_kindtypeNONE;
2654 type = error_mark_node;
2661 /* build_decl uses the current lineno and input_filename to set the decl
2662 source info. So, I've putzed with ffestd and ffeste code to update that
2663 source info to point to the appropriate statement just before calling
2664 ffecom_do_entrypoint (which calls this fn). */
2666 start_function (ffecom_get_external_identifier_ (fn),
2668 0, /* nested/inline */
2669 1); /* TREE_PUBLIC */
2671 if (((g = ffesymbol_global (fn)) != NULL)
2672 && ((ffeglobal_type (g) == gt)
2673 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2675 ffeglobal_set_hook (g, current_function_decl);
2678 /* Reset args in master arg list so they get retransitioned. */
2680 for (item = ffecom_master_arglist_;
2682 item = ffebld_trail (item))
2687 arg = ffebld_head (item);
2688 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2689 continue; /* Alternate return or some such thing. */
2690 s = ffebld_symter (arg);
2691 ffesymbol_hook (s).decl_tree = NULL_TREE;
2692 ffesymbol_hook (s).length_tree = NULL_TREE;
2695 /* Build dummy arg list for this entry point. */
2697 if (charfunc || cmplxfunc)
2698 { /* Prepend arg for where result goes. */
2703 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2705 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2707 result = ffecom_get_invented_identifier ("__g77_%s", "result");
2709 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2712 length = ffecom_char_enhance_arg_ (&type, fn);
2714 length = NULL_TREE; /* Not ref'd if !charfunc. */
2716 type = build_pointer_type (type);
2717 result = build_decl (PARM_DECL, result, type);
2719 push_parm_decl (result);
2720 ffecom_func_result_ = result;
2724 push_parm_decl (length);
2725 ffecom_func_length_ = length;
2729 result = DECL_RESULT (current_function_decl);
2731 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2733 store_parm_decls (0);
2735 ffecom_start_compstmt ();
2736 /* Disallow temp vars at this level. */
2737 current_binding_level->prep_state = 2;
2739 /* Make local var to hold return type for multi-type master fn. */
2743 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
2745 multi_retval = build_decl (VAR_DECL, multi_retval,
2746 ffecom_multi_type_node_);
2747 multi_retval = start_decl (multi_retval, FALSE);
2748 finish_decl (multi_retval, NULL_TREE, FALSE);
2751 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2753 /* Here we emit the actual code for the entry point. */
2759 tree arglist = NULL_TREE;
2760 tree *plist = &arglist;
2766 /* Prepare actual arg list based on master arg list. */
2768 for (list = ffecom_master_arglist_;
2770 list = ffebld_trail (list))
2772 arg = ffebld_head (list);
2773 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2775 s = ffebld_symter (arg);
2776 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2777 || ffesymbol_hook (s).decl_tree == error_mark_node)
2778 actarg = null_pointer_node; /* We don't have this arg. */
2780 actarg = ffesymbol_hook (s).decl_tree;
2781 *plist = build_tree_list (NULL_TREE, actarg);
2782 plist = &TREE_CHAIN (*plist);
2785 /* This code appends the length arguments for character
2786 variables/arrays. */
2788 for (list = ffecom_master_arglist_;
2790 list = ffebld_trail (list))
2792 arg = ffebld_head (list);
2793 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2795 s = ffebld_symter (arg);
2796 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2797 continue; /* Only looking for CHARACTER arguments. */
2798 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2799 continue; /* Only looking for variables and arrays. */
2800 if (ffesymbol_hook (s).length_tree == NULL_TREE
2801 || ffesymbol_hook (s).length_tree == error_mark_node)
2802 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2804 actarg = ffesymbol_hook (s).length_tree;
2805 *plist = build_tree_list (NULL_TREE, actarg);
2806 plist = &TREE_CHAIN (*plist);
2809 /* Prepend character-value return info to actual arg list. */
2813 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2814 TREE_CHAIN (prepend)
2815 = build_tree_list (NULL_TREE, ffecom_func_length_);
2816 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2820 /* Prepend multi-type return value to actual arg list. */
2825 = build_tree_list (NULL_TREE,
2826 ffecom_1 (ADDR_EXPR,
2827 build_pointer_type (TREE_TYPE (multi_retval)),
2829 TREE_CHAIN (prepend) = arglist;
2833 /* Prepend my entry-point number to the actual arg list. */
2835 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2836 TREE_CHAIN (prepend) = arglist;
2839 /* Build the call to the master function. */
2841 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2842 call = ffecom_3s (CALL_EXPR,
2843 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2844 master_fn, arglist, NULL_TREE);
2846 /* Decide whether the master function is a function or subroutine, and
2847 handle the return value for my entry point. */
2849 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2852 expand_expr_stmt (call);
2853 expand_null_return ();
2855 else if (multi && cmplxfunc)
2857 expand_expr_stmt (call);
2859 = ffecom_1 (INDIRECT_REF,
2860 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2862 result = ffecom_modify (NULL_TREE, result,
2863 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
2865 ffecom_multi_fields_[bt][kt]));
2866 expand_expr_stmt (result);
2867 expand_null_return ();
2871 expand_expr_stmt (call);
2873 = ffecom_modify (NULL_TREE, result,
2874 convert (TREE_TYPE (result),
2875 ffecom_2 (COMPONENT_REF,
2876 ffecom_tree_type[bt][kt],
2878 ffecom_multi_fields_[bt][kt])));
2879 expand_return (result);
2884 = ffecom_1 (INDIRECT_REF,
2885 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2887 result = ffecom_modify (NULL_TREE, result, call);
2888 expand_expr_stmt (result);
2889 expand_null_return ();
2893 result = ffecom_modify (NULL_TREE,
2895 convert (TREE_TYPE (result),
2897 expand_return (result);
2901 ffecom_end_compstmt ();
2903 finish_function (0);
2905 lineno = old_lineno;
2906 input_filename = old_input_filename;
2908 ffecom_doing_entry_ = FALSE;
2911 /* Transform expr into gcc tree with possible destination
2913 Recursive descent on expr while making corresponding tree nodes and
2914 attaching type info and such. If destination supplied and compatible
2915 with temporary that would be made in certain cases, temporary isn't
2916 made, destination used instead, and dest_used flag set TRUE. */
2919 ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
2920 bool *dest_used, bool assignp, bool widenp)
2925 ffeinfoBasictype bt;
2928 tree dt; /* decl_tree for an ffesymbol. */
2929 tree tree_type, tree_type_x;
2932 enum tree_code code;
2934 assert (expr != NULL);
2936 if (dest_used != NULL)
2939 bt = ffeinfo_basictype (ffebld_info (expr));
2940 kt = ffeinfo_kindtype (ffebld_info (expr));
2941 tree_type = ffecom_tree_type[bt][kt];
2943 /* Widen integral arithmetic as desired while preserving signedness. */
2944 tree_type_x = NULL_TREE;
2945 if (widenp && tree_type
2946 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
2947 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
2948 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
2950 switch (ffebld_op (expr))
2952 case FFEBLD_opACCTER:
2955 ffebit bits = ffebld_accter_bits (expr);
2956 ffetargetOffset source_offset = 0;
2957 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
2960 assert (dest_offset == 0
2961 || (bt == FFEINFO_basictypeCHARACTER
2962 && kt == FFEINFO_kindtypeCHARACTER1));
2967 ffebldConstantUnion cu;
2970 ffebldConstantArray ca = ffebld_accter (expr);
2972 ffebit_test (bits, source_offset, &value, &length);
2978 for (i = 0; i < length; ++i)
2980 cu = ffebld_constantarray_get (ca, bt, kt,
2983 t = ffecom_constantunion (&cu, bt, kt, tree_type);
2986 && dest_offset != 0)
2987 purpose = build_int_2 (dest_offset, 0);
2989 purpose = NULL_TREE;
2991 if (list == NULL_TREE)
2992 list = item = build_tree_list (purpose, t);
2995 TREE_CHAIN (item) = build_tree_list (purpose, t);
2996 item = TREE_CHAIN (item);
3000 source_offset += length;
3001 dest_offset += length;
3005 item = build_int_2 ((ffebld_accter_size (expr)
3006 + ffebld_accter_pad (expr)) - 1, 0);
3007 ffebit_kill (ffebld_accter_bits (expr));
3008 TREE_TYPE (item) = ffecom_integer_type_node;
3012 build_range_type (ffecom_integer_type_node,
3013 ffecom_integer_zero_node,
3015 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3016 TREE_CONSTANT (list) = 1;
3017 TREE_STATIC (list) = 1;
3020 case FFEBLD_opARRTER:
3025 if (ffebld_arrter_pad (expr) == 0)
3029 assert (bt == FFEINFO_basictypeCHARACTER
3030 && kt == FFEINFO_kindtypeCHARACTER1);
3032 /* Becomes PURPOSE first time through loop. */
3033 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3036 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3038 ffebldConstantUnion cu
3039 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3041 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3043 if (list == NULL_TREE)
3044 /* Assume item is PURPOSE first time through loop. */
3045 list = item = build_tree_list (item, t);
3048 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3049 item = TREE_CHAIN (item);
3054 item = build_int_2 ((ffebld_arrter_size (expr)
3055 + ffebld_arrter_pad (expr)) - 1, 0);
3056 TREE_TYPE (item) = ffecom_integer_type_node;
3060 build_range_type (ffecom_integer_type_node,
3061 ffecom_integer_zero_node,
3063 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3064 TREE_CONSTANT (list) = 1;
3065 TREE_STATIC (list) = 1;
3068 case FFEBLD_opCONTER:
3069 assert (ffebld_conter_pad (expr) == 0);
3071 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3075 case FFEBLD_opSYMTER:
3076 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3077 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3078 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3079 s = ffebld_symter (expr);
3080 t = ffesymbol_hook (s).decl_tree;
3083 { /* ASSIGN'ed-label expr. */
3084 if (ffe_is_ugly_assign ())
3086 /* User explicitly wants ASSIGN'ed variables to be at the same
3087 memory address as the variables when used in non-ASSIGN
3088 contexts. That can make old, arcane, non-standard code
3089 work, but don't try to do it when a pointer wouldn't fit
3090 in the normal variable (take other approach, and warn,
3095 s = ffecom_sym_transform_ (s);
3096 t = ffesymbol_hook (s).decl_tree;
3097 assert (t != NULL_TREE);
3100 if (t == error_mark_node)
3103 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3104 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3106 if (ffesymbol_hook (s).addr)
3107 t = ffecom_1 (INDIRECT_REF,
3108 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3112 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3114 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3115 FFEBAD_severityWARNING);
3116 ffebad_string (ffesymbol_text (s));
3117 ffebad_here (0, ffesymbol_where_line (s),
3118 ffesymbol_where_column (s));
3123 /* Don't use the normal variable's tree for ASSIGN, though mark
3124 it as in the system header (housekeeping). Use an explicit,
3125 specially created sibling that is known to be wide enough
3126 to hold pointers to labels. */
3129 && TREE_CODE (t) == VAR_DECL)
3130 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3132 t = ffesymbol_hook (s).assign_tree;
3135 s = ffecom_sym_transform_assign_ (s);
3136 t = ffesymbol_hook (s).assign_tree;
3137 assert (t != NULL_TREE);
3144 s = ffecom_sym_transform_ (s);
3145 t = ffesymbol_hook (s).decl_tree;
3146 assert (t != NULL_TREE);
3148 if (ffesymbol_hook (s).addr)
3149 t = ffecom_1 (INDIRECT_REF,
3150 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3154 case FFEBLD_opARRAYREF:
3155 return ffecom_arrayref_ (NULL_TREE, expr, 0);
3157 case FFEBLD_opUPLUS:
3158 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3159 return ffecom_1 (NOP_EXPR, tree_type, left);
3161 case FFEBLD_opPAREN:
3162 /* ~~~Make sure Fortran rules respected here */
3163 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3164 return ffecom_1 (NOP_EXPR, tree_type, left);
3166 case FFEBLD_opUMINUS:
3167 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3170 tree_type = tree_type_x;
3171 left = convert (tree_type, left);
3173 return ffecom_1 (NEGATE_EXPR, tree_type, left);
3176 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3177 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3180 tree_type = tree_type_x;
3181 left = convert (tree_type, left);
3182 right = convert (tree_type, right);
3184 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
3186 case FFEBLD_opSUBTRACT:
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 (MINUS_EXPR, tree_type, left, right);
3197 case FFEBLD_opMULTIPLY:
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 (MULT_EXPR, tree_type, left, right);
3208 case FFEBLD_opDIVIDE:
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_tree_divide_ (tree_type, left, right,
3218 dest_tree, dest, dest_used,
3219 ffebld_nonter_hook (expr));
3221 case FFEBLD_opPOWER:
3223 ffebld left = ffebld_left (expr);
3224 ffebld right = ffebld_right (expr);
3226 ffeinfoKindtype rtkt;
3227 ffeinfoKindtype ltkt;
3230 switch (ffeinfo_basictype (ffebld_info (right)))
3233 case FFEINFO_basictypeINTEGER:
3236 item = ffecom_expr_power_integer_ (expr);
3237 if (item != NULL_TREE)
3241 rtkt = FFEINFO_kindtypeINTEGER1;
3242 switch (ffeinfo_basictype (ffebld_info (left)))
3244 case FFEINFO_basictypeINTEGER:
3245 if ((ffeinfo_kindtype (ffebld_info (left))
3246 == FFEINFO_kindtypeINTEGER4)
3247 || (ffeinfo_kindtype (ffebld_info (right))
3248 == FFEINFO_kindtypeINTEGER4))
3250 code = FFECOM_gfrtPOW_QQ;
3251 ltkt = FFEINFO_kindtypeINTEGER4;
3252 rtkt = FFEINFO_kindtypeINTEGER4;
3256 code = FFECOM_gfrtPOW_II;
3257 ltkt = FFEINFO_kindtypeINTEGER1;
3261 case FFEINFO_basictypeREAL:
3262 if (ffeinfo_kindtype (ffebld_info (left))
3263 == FFEINFO_kindtypeREAL1)
3265 code = FFECOM_gfrtPOW_RI;
3266 ltkt = FFEINFO_kindtypeREAL1;
3270 code = FFECOM_gfrtPOW_DI;
3271 ltkt = FFEINFO_kindtypeREAL2;
3275 case FFEINFO_basictypeCOMPLEX:
3276 if (ffeinfo_kindtype (ffebld_info (left))
3277 == FFEINFO_kindtypeREAL1)
3279 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3280 ltkt = FFEINFO_kindtypeREAL1;
3284 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3285 ltkt = FFEINFO_kindtypeREAL2;
3290 assert ("bad pow_*i" == NULL);
3291 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3292 ltkt = FFEINFO_kindtypeREAL1;
3295 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
3296 left = ffeexpr_convert (left, NULL, NULL,
3297 ffeinfo_basictype (ffebld_info (left)),
3299 FFETARGET_charactersizeNONE,
3300 FFEEXPR_contextLET);
3301 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3302 right = ffeexpr_convert (right, NULL, NULL,
3303 FFEINFO_basictypeINTEGER,
3305 FFETARGET_charactersizeNONE,
3306 FFEEXPR_contextLET);
3309 case FFEINFO_basictypeREAL:
3310 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3311 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3312 FFEINFO_kindtypeREALDOUBLE, 0,
3313 FFETARGET_charactersizeNONE,
3314 FFEEXPR_contextLET);
3315 if (ffeinfo_kindtype (ffebld_info (right))
3316 == FFEINFO_kindtypeREAL1)
3317 right = ffeexpr_convert (right, NULL, NULL,
3318 FFEINFO_basictypeREAL,
3319 FFEINFO_kindtypeREALDOUBLE, 0,
3320 FFETARGET_charactersizeNONE,
3321 FFEEXPR_contextLET);
3322 /* We used to call FFECOM_gfrtPOW_DD here,
3323 which passes arguments by reference. */
3324 code = FFECOM_gfrtL_POW;
3325 /* Pass arguments by value. */
3329 case FFEINFO_basictypeCOMPLEX:
3330 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3331 left = ffeexpr_convert (left, NULL, NULL,
3332 FFEINFO_basictypeCOMPLEX,
3333 FFEINFO_kindtypeREALDOUBLE, 0,
3334 FFETARGET_charactersizeNONE,
3335 FFEEXPR_contextLET);
3336 if (ffeinfo_kindtype (ffebld_info (right))
3337 == FFEINFO_kindtypeREAL1)
3338 right = ffeexpr_convert (right, NULL, NULL,
3339 FFEINFO_basictypeCOMPLEX,
3340 FFEINFO_kindtypeREALDOUBLE, 0,
3341 FFETARGET_charactersizeNONE,
3342 FFEEXPR_contextLET);
3343 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
3344 ref = TRUE; /* Pass arguments by reference. */
3348 assert ("bad pow_x*" == NULL);
3349 code = FFECOM_gfrtPOW_II;
3352 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3353 ffecom_gfrt_kindtype (code),
3354 (ffe_is_f2c_library ()
3355 && ffecom_gfrt_complex_[code]),
3356 tree_type, left, right,
3357 dest_tree, dest, dest_used,
3358 NULL_TREE, FALSE, ref,
3359 ffebld_nonter_hook (expr));
3365 case FFEINFO_basictypeLOGICAL:
3366 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
3367 return convert (tree_type, item);
3369 case FFEINFO_basictypeINTEGER:
3370 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3371 ffecom_expr (ffebld_left (expr)));
3374 assert ("NOT bad basictype" == NULL);
3376 case FFEINFO_basictypeANY:
3377 return error_mark_node;
3381 case FFEBLD_opFUNCREF:
3382 assert (ffeinfo_basictype (ffebld_info (expr))
3383 != FFEINFO_basictypeCHARACTER);
3385 case FFEBLD_opSUBRREF:
3386 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3387 == FFEINFO_whereINTRINSIC)
3388 { /* Invocation of an intrinsic. */
3389 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3393 s = ffebld_symter (ffebld_left (expr));
3394 dt = ffesymbol_hook (s).decl_tree;
3395 if (dt == NULL_TREE)
3397 s = ffecom_sym_transform_ (s);
3398 dt = ffesymbol_hook (s).decl_tree;
3400 if (dt == error_mark_node)
3403 if (ffesymbol_hook (s).addr)
3406 item = ffecom_1_fn (dt);
3408 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3409 args = ffecom_list_expr (ffebld_right (expr));
3411 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
3413 if (args == error_mark_node)
3414 return error_mark_node;
3416 item = ffecom_call_ (item, kt,
3417 ffesymbol_is_f2c (s)
3418 && (bt == FFEINFO_basictypeCOMPLEX)
3419 && (ffesymbol_where (s)
3420 != FFEINFO_whereCONSTANT),
3423 dest_tree, dest, dest_used,
3424 error_mark_node, FALSE,
3425 ffebld_nonter_hook (expr));
3426 TREE_SIDE_EFFECTS (item) = 1;
3432 case FFEINFO_basictypeLOGICAL:
3434 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3435 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3436 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3437 return convert (tree_type, item);
3439 case FFEINFO_basictypeINTEGER:
3440 return ffecom_2 (BIT_AND_EXPR, tree_type,
3441 ffecom_expr (ffebld_left (expr)),
3442 ffecom_expr (ffebld_right (expr)));
3445 assert ("AND bad basictype" == NULL);
3447 case FFEINFO_basictypeANY:
3448 return error_mark_node;
3455 case FFEINFO_basictypeLOGICAL:
3457 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3458 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3459 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3460 return convert (tree_type, item);
3462 case FFEINFO_basictypeINTEGER:
3463 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3464 ffecom_expr (ffebld_left (expr)),
3465 ffecom_expr (ffebld_right (expr)));
3468 assert ("OR bad basictype" == NULL);
3470 case FFEINFO_basictypeANY:
3471 return error_mark_node;
3479 case FFEINFO_basictypeLOGICAL:
3481 = ffecom_2 (NE_EXPR, integer_type_node,
3482 ffecom_expr (ffebld_left (expr)),
3483 ffecom_expr (ffebld_right (expr)));
3484 return convert (tree_type, ffecom_truth_value (item));
3486 case FFEINFO_basictypeINTEGER:
3487 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3488 ffecom_expr (ffebld_left (expr)),
3489 ffecom_expr (ffebld_right (expr)));
3492 assert ("XOR/NEQV bad basictype" == NULL);
3494 case FFEINFO_basictypeANY:
3495 return error_mark_node;
3502 case FFEINFO_basictypeLOGICAL:
3504 = ffecom_2 (EQ_EXPR, integer_type_node,
3505 ffecom_expr (ffebld_left (expr)),
3506 ffecom_expr (ffebld_right (expr)));
3507 return convert (tree_type, ffecom_truth_value (item));
3509 case FFEINFO_basictypeINTEGER:
3511 ffecom_1 (BIT_NOT_EXPR, tree_type,
3512 ffecom_2 (BIT_XOR_EXPR, tree_type,
3513 ffecom_expr (ffebld_left (expr)),
3514 ffecom_expr (ffebld_right (expr))));
3517 assert ("EQV bad basictype" == NULL);
3519 case FFEINFO_basictypeANY:
3520 return error_mark_node;
3524 case FFEBLD_opCONVERT:
3525 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3526 return error_mark_node;
3530 case FFEINFO_basictypeLOGICAL:
3531 case FFEINFO_basictypeINTEGER:
3532 case FFEINFO_basictypeREAL:
3533 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3535 case FFEINFO_basictypeCOMPLEX:
3536 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3538 case FFEINFO_basictypeINTEGER:
3539 case FFEINFO_basictypeLOGICAL:
3540 case FFEINFO_basictypeREAL:
3541 item = ffecom_expr (ffebld_left (expr));
3542 if (item == error_mark_node)
3543 return error_mark_node;
3544 /* convert() takes care of converting to the subtype first,
3545 at least in gcc-2.7.2. */
3546 item = convert (tree_type, item);
3549 case FFEINFO_basictypeCOMPLEX:
3550 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3553 assert ("CONVERT COMPLEX bad basictype" == NULL);
3555 case FFEINFO_basictypeANY:
3556 return error_mark_node;
3561 assert ("CONVERT bad basictype" == NULL);
3563 case FFEINFO_basictypeANY:
3564 return error_mark_node;
3570 goto relational; /* :::::::::::::::::::: */
3574 goto relational; /* :::::::::::::::::::: */
3578 goto relational; /* :::::::::::::::::::: */
3582 goto relational; /* :::::::::::::::::::: */
3586 goto relational; /* :::::::::::::::::::: */
3591 relational: /* :::::::::::::::::::: */
3592 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3594 case FFEINFO_basictypeLOGICAL:
3595 case FFEINFO_basictypeINTEGER:
3596 case FFEINFO_basictypeREAL:
3597 item = ffecom_2 (code, integer_type_node,
3598 ffecom_expr (ffebld_left (expr)),
3599 ffecom_expr (ffebld_right (expr)));
3600 return convert (tree_type, item);
3602 case FFEINFO_basictypeCOMPLEX:
3603 assert (code == EQ_EXPR || code == NE_EXPR);
3606 tree arg1 = ffecom_expr (ffebld_left (expr));
3607 tree arg2 = ffecom_expr (ffebld_right (expr));
3609 if (arg1 == error_mark_node || arg2 == error_mark_node)
3610 return error_mark_node;
3612 arg1 = ffecom_save_tree (arg1);
3613 arg2 = ffecom_save_tree (arg2);
3615 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3617 real_type = TREE_TYPE (TREE_TYPE (arg1));
3618 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3622 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3623 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3627 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3628 ffecom_2 (EQ_EXPR, integer_type_node,
3629 ffecom_1 (REALPART_EXPR, real_type, arg1),
3630 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3631 ffecom_2 (EQ_EXPR, integer_type_node,
3632 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3633 ffecom_1 (IMAGPART_EXPR, real_type,
3635 if (code == EQ_EXPR)
3636 item = ffecom_truth_value (item);
3638 item = ffecom_truth_value_invert (item);
3639 return convert (tree_type, item);
3642 case FFEINFO_basictypeCHARACTER:
3644 ffebld left = ffebld_left (expr);
3645 ffebld right = ffebld_right (expr);
3651 /* f2c run-time functions do the implicit blank-padding for us,
3652 so we don't usually have to implement blank-padding ourselves.
3653 (The exception is when we pass an argument to a separately
3654 compiled statement function -- if we know the arg is not the
3655 same length as the dummy, we must truncate or extend it. If
3656 we "inline" statement functions, that necessity goes away as
3659 Strip off the CONVERT operators that blank-pad. (Truncation by
3660 CONVERT shouldn't happen here, but it can happen in
3663 while (ffebld_op (left) == FFEBLD_opCONVERT)
3664 left = ffebld_left (left);
3665 while (ffebld_op (right) == FFEBLD_opCONVERT)
3666 right = ffebld_left (right);
3668 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3669 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3671 if (left_tree == error_mark_node || left_length == error_mark_node
3672 || right_tree == error_mark_node
3673 || right_length == error_mark_node)
3674 return error_mark_node;
3676 if ((ffebld_size_known (left) == 1)
3677 && (ffebld_size_known (right) == 1))
3680 = ffecom_1 (INDIRECT_REF,
3681 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3684 = ffecom_1 (INDIRECT_REF,
3685 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3689 = ffecom_2 (code, integer_type_node,
3690 ffecom_2 (ARRAY_REF,
3691 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3694 ffecom_2 (ARRAY_REF,
3695 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3701 item = build_tree_list (NULL_TREE, left_tree);
3702 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3703 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3705 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3706 = build_tree_list (NULL_TREE, right_length);
3707 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
3708 item = ffecom_2 (code, integer_type_node,
3710 convert (TREE_TYPE (item),
3711 integer_zero_node));
3713 item = convert (tree_type, item);
3719 assert ("relational bad basictype" == NULL);
3721 case FFEINFO_basictypeANY:
3722 return error_mark_node;
3726 case FFEBLD_opPERCENT_LOC:
3727 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3728 return convert (tree_type, item);
3732 case FFEBLD_opBOUNDS:
3733 case FFEBLD_opREPEAT:
3734 case FFEBLD_opLABTER:
3735 case FFEBLD_opLABTOK:
3736 case FFEBLD_opIMPDO:
3737 case FFEBLD_opCONCATENATE:
3738 case FFEBLD_opSUBSTR:
3740 assert ("bad op" == NULL);
3743 return error_mark_node;
3747 assert ("didn't think anything got here anymore!!" == NULL);
3749 switch (ffebld_arity (expr))
3752 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3753 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3754 if (TREE_OPERAND (item, 0) == error_mark_node
3755 || TREE_OPERAND (item, 1) == error_mark_node)
3756 return error_mark_node;
3760 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3761 if (TREE_OPERAND (item, 0) == error_mark_node)
3762 return error_mark_node;
3773 /* Returns the tree that does the intrinsic invocation.
3775 Note: this function applies only to intrinsics returning
3776 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3780 ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
3781 ffebld dest, bool *dest_used)
3784 tree saved_expr1; /* For those who need it. */
3785 tree saved_expr2; /* For those who need it. */
3786 ffeinfoBasictype bt;
3790 tree real_type; /* REAL type corresponding to COMPLEX. */
3792 ffebld list = ffebld_right (expr); /* List of (some) args. */
3793 ffebld arg1; /* For handy reference. */
3796 ffeintrinImp codegen_imp;
3799 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3801 if (dest_used != NULL)
3804 bt = ffeinfo_basictype (ffebld_info (expr));
3805 kt = ffeinfo_kindtype (ffebld_info (expr));
3806 tree_type = ffecom_tree_type[bt][kt];
3810 arg1 = ffebld_head (list);
3811 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3812 return error_mark_node;
3813 if ((list = ffebld_trail (list)) != NULL)
3815 arg2 = ffebld_head (list);
3816 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3817 return error_mark_node;
3818 if ((list = ffebld_trail (list)) != NULL)
3820 arg3 = ffebld_head (list);
3821 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3822 return error_mark_node;
3831 arg1 = arg2 = arg3 = NULL;
3833 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3834 args. This is used by the MAX/MIN expansions. */
3837 arg1_type = ffecom_tree_type
3838 [ffeinfo_basictype (ffebld_info (arg1))]
3839 [ffeinfo_kindtype (ffebld_info (arg1))];
3841 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3844 /* There are several ways for each of the cases in the following switch
3845 statements to exit (from simplest to use to most complicated):
3847 break; (when expr_tree == NULL)
3849 A standard call is made to the specific intrinsic just as if it had been
3850 passed in as a dummy procedure and called as any old procedure. This
3851 method can produce slower code but in some cases it's the easiest way for
3852 now. However, if a (presumably faster) direct call is available,
3853 that is used, so this is the easiest way in many more cases now.
3855 gfrt = FFECOM_gfrtWHATEVER;
3858 gfrt contains the gfrt index of a library function to call, passing the
3859 argument(s) by value rather than by reference. Used when a more
3860 careful choice of library function is needed than that provided
3861 by the vanilla `break;'.
3865 The expr_tree has been completely set up and is ready to be returned
3866 as is. No further actions are taken. Use this when the tree is not
3867 in the simple form for one of the arity_n labels. */
3869 /* For info on how the switch statement cases were written, see the files
3870 enclosed in comments below the switch statement. */
3872 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
3873 gfrt = ffeintrin_gfrt_direct (codegen_imp);
3874 if (gfrt == FFECOM_gfrt)
3875 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
3877 switch (codegen_imp)
3879 case FFEINTRIN_impABS:
3880 case FFEINTRIN_impCABS:
3881 case FFEINTRIN_impCDABS:
3882 case FFEINTRIN_impDABS:
3883 case FFEINTRIN_impIABS:
3884 if (ffeinfo_basictype (ffebld_info (arg1))
3885 == FFEINFO_basictypeCOMPLEX)
3887 if (kt == FFEINFO_kindtypeREAL1)
3888 gfrt = FFECOM_gfrtCABS;
3889 else if (kt == FFEINFO_kindtypeREAL2)
3890 gfrt = FFECOM_gfrtCDABS;
3893 return ffecom_1 (ABS_EXPR, tree_type,
3894 convert (tree_type, ffecom_expr (arg1)));
3896 case FFEINTRIN_impACOS:
3897 case FFEINTRIN_impDACOS:
3900 case FFEINTRIN_impAIMAG:
3901 case FFEINTRIN_impDIMAG:
3902 case FFEINTRIN_impIMAGPART:
3903 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
3904 arg1_type = TREE_TYPE (arg1_type);
3906 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
3910 ffecom_1 (IMAGPART_EXPR, arg1_type,
3911 ffecom_expr (arg1)));
3913 case FFEINTRIN_impAINT:
3914 case FFEINTRIN_impDINT:
3916 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
3917 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
3918 #else /* in the meantime, must use floor to avoid range problems with ints */
3919 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
3920 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3923 ffecom_3 (COND_EXPR, double_type_node,
3925 (ffecom_2 (GE_EXPR, integer_type_node,
3928 ffecom_float_zero_))),
3929 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3930 build_tree_list (NULL_TREE,
3931 convert (double_type_node,
3934 ffecom_1 (NEGATE_EXPR, double_type_node,
3935 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3936 build_tree_list (NULL_TREE,
3937 convert (double_type_node,
3938 ffecom_1 (NEGATE_EXPR,
3946 case FFEINTRIN_impANINT:
3947 case FFEINTRIN_impDNINT:
3948 #if 0 /* This way of doing it won't handle real
3949 numbers of large magnitudes. */
3950 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3951 expr_tree = convert (tree_type,
3952 convert (integer_type_node,
3953 ffecom_3 (COND_EXPR, tree_type,
3958 ffecom_float_zero_)),
3959 ffecom_2 (PLUS_EXPR,
3962 ffecom_float_half_),
3963 ffecom_2 (MINUS_EXPR,
3966 ffecom_float_half_))));
3968 #else /* So we instead call floor. */
3969 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
3970 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3973 ffecom_3 (COND_EXPR, double_type_node,
3975 (ffecom_2 (GE_EXPR, integer_type_node,
3978 ffecom_float_zero_))),
3979 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3980 build_tree_list (NULL_TREE,
3981 convert (double_type_node,
3982 ffecom_2 (PLUS_EXPR,
3986 ffecom_float_half_)))),
3988 ffecom_1 (NEGATE_EXPR, double_type_node,
3989 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3990 build_tree_list (NULL_TREE,
3991 convert (double_type_node,
3992 ffecom_2 (MINUS_EXPR,
3995 ffecom_float_half_),
4002 case FFEINTRIN_impASIN:
4003 case FFEINTRIN_impDASIN:
4004 case FFEINTRIN_impATAN:
4005 case FFEINTRIN_impDATAN:
4006 case FFEINTRIN_impATAN2:
4007 case FFEINTRIN_impDATAN2:
4010 case FFEINTRIN_impCHAR:
4011 case FFEINTRIN_impACHAR:
4013 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
4015 tempvar = ffebld_nonter_hook (expr);
4019 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4021 expr_tree = ffecom_modify (tmv,
4022 ffecom_2 (ARRAY_REF, tmv, tempvar,
4024 convert (tmv, ffecom_expr (arg1)));
4026 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4029 expr_tree = ffecom_1 (ADDR_EXPR,
4030 build_pointer_type (TREE_TYPE (expr_tree)),
4034 case FFEINTRIN_impCMPLX:
4035 case FFEINTRIN_impDCMPLX:
4038 convert (tree_type, ffecom_expr (arg1));
4040 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4042 ffecom_2 (COMPLEX_EXPR, tree_type,
4043 convert (real_type, ffecom_expr (arg1)),
4045 ffecom_expr (arg2)));
4047 case FFEINTRIN_impCOMPLEX:
4049 ffecom_2 (COMPLEX_EXPR, tree_type,
4051 ffecom_expr (arg2));
4053 case FFEINTRIN_impCONJG:
4054 case FFEINTRIN_impDCONJG:
4058 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4059 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4061 ffecom_2 (COMPLEX_EXPR, tree_type,
4062 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4063 ffecom_1 (NEGATE_EXPR, real_type,
4064 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4067 case FFEINTRIN_impCOS:
4068 case FFEINTRIN_impCCOS:
4069 case FFEINTRIN_impCDCOS:
4070 case FFEINTRIN_impDCOS:
4071 if (bt == FFEINFO_basictypeCOMPLEX)
4073 if (kt == FFEINFO_kindtypeREAL1)
4074 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4075 else if (kt == FFEINFO_kindtypeREAL2)
4076 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4080 case FFEINTRIN_impCOSH:
4081 case FFEINTRIN_impDCOSH:
4084 case FFEINTRIN_impDBLE:
4085 case FFEINTRIN_impDFLOAT:
4086 case FFEINTRIN_impDREAL:
4087 case FFEINTRIN_impFLOAT:
4088 case FFEINTRIN_impIDINT:
4089 case FFEINTRIN_impIFIX:
4090 case FFEINTRIN_impINT2:
4091 case FFEINTRIN_impINT8:
4092 case FFEINTRIN_impINT:
4093 case FFEINTRIN_impLONG:
4094 case FFEINTRIN_impREAL:
4095 case FFEINTRIN_impSHORT:
4096 case FFEINTRIN_impSNGL:
4097 return convert (tree_type, ffecom_expr (arg1));
4099 case FFEINTRIN_impDIM:
4100 case FFEINTRIN_impDDIM:
4101 case FFEINTRIN_impIDIM:
4102 saved_expr1 = ffecom_save_tree (convert (tree_type,
4103 ffecom_expr (arg1)));
4104 saved_expr2 = ffecom_save_tree (convert (tree_type,
4105 ffecom_expr (arg2)));
4107 ffecom_3 (COND_EXPR, tree_type,
4109 (ffecom_2 (GT_EXPR, integer_type_node,
4112 ffecom_2 (MINUS_EXPR, tree_type,
4115 convert (tree_type, ffecom_float_zero_));
4117 case FFEINTRIN_impDPROD:
4119 ffecom_2 (MULT_EXPR, tree_type,
4120 convert (tree_type, ffecom_expr (arg1)),
4121 convert (tree_type, ffecom_expr (arg2)));
4123 case FFEINTRIN_impEXP:
4124 case FFEINTRIN_impCDEXP:
4125 case FFEINTRIN_impCEXP:
4126 case FFEINTRIN_impDEXP:
4127 if (bt == FFEINFO_basictypeCOMPLEX)
4129 if (kt == FFEINFO_kindtypeREAL1)
4130 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4131 else if (kt == FFEINFO_kindtypeREAL2)
4132 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4136 case FFEINTRIN_impICHAR:
4137 case FFEINTRIN_impIACHAR:
4138 #if 0 /* The simple approach. */
4139 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4141 = ffecom_1 (INDIRECT_REF,
4142 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4145 = ffecom_2 (ARRAY_REF,
4146 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4149 return convert (tree_type, expr_tree);
4150 #else /* The more interesting (and more optimal) approach. */
4151 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4152 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4155 convert (tree_type, integer_zero_node));
4159 case FFEINTRIN_impINDEX:
4162 case FFEINTRIN_impLEN:
4164 break; /* The simple approach. */
4166 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4169 case FFEINTRIN_impLGE:
4170 case FFEINTRIN_impLGT:
4171 case FFEINTRIN_impLLE:
4172 case FFEINTRIN_impLLT:
4175 case FFEINTRIN_impLOG:
4176 case FFEINTRIN_impALOG:
4177 case FFEINTRIN_impCDLOG:
4178 case FFEINTRIN_impCLOG:
4179 case FFEINTRIN_impDLOG:
4180 if (bt == FFEINFO_basictypeCOMPLEX)
4182 if (kt == FFEINFO_kindtypeREAL1)
4183 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4184 else if (kt == FFEINFO_kindtypeREAL2)
4185 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4189 case FFEINTRIN_impLOG10:
4190 case FFEINTRIN_impALOG10:
4191 case FFEINTRIN_impDLOG10:
4192 if (gfrt != FFECOM_gfrt)
4193 break; /* Already picked one, stick with it. */
4195 if (kt == FFEINFO_kindtypeREAL1)
4196 /* We used to call FFECOM_gfrtALOG10 here. */
4197 gfrt = FFECOM_gfrtL_LOG10;
4198 else if (kt == FFEINFO_kindtypeREAL2)
4199 /* We used to call FFECOM_gfrtDLOG10 here. */
4200 gfrt = FFECOM_gfrtL_LOG10;
4203 case FFEINTRIN_impMAX:
4204 case FFEINTRIN_impAMAX0:
4205 case FFEINTRIN_impAMAX1:
4206 case FFEINTRIN_impDMAX1:
4207 case FFEINTRIN_impMAX0:
4208 case FFEINTRIN_impMAX1:
4209 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4210 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4212 arg1_type = tree_type;
4213 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4214 convert (arg1_type, ffecom_expr (arg1)),
4215 convert (arg1_type, ffecom_expr (arg2)));
4216 for (; list != NULL; list = ffebld_trail (list))
4218 if ((ffebld_head (list) == NULL)
4219 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4221 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4224 ffecom_expr (ffebld_head (list))));
4226 return convert (tree_type, expr_tree);
4228 case FFEINTRIN_impMIN:
4229 case FFEINTRIN_impAMIN0:
4230 case FFEINTRIN_impAMIN1:
4231 case FFEINTRIN_impDMIN1:
4232 case FFEINTRIN_impMIN0:
4233 case FFEINTRIN_impMIN1:
4234 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4235 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4237 arg1_type = tree_type;
4238 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4239 convert (arg1_type, ffecom_expr (arg1)),
4240 convert (arg1_type, ffecom_expr (arg2)));
4241 for (; list != NULL; list = ffebld_trail (list))
4243 if ((ffebld_head (list) == NULL)
4244 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4246 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4249 ffecom_expr (ffebld_head (list))));
4251 return convert (tree_type, expr_tree);
4253 case FFEINTRIN_impMOD:
4254 case FFEINTRIN_impAMOD:
4255 case FFEINTRIN_impDMOD:
4256 if (bt != FFEINFO_basictypeREAL)
4257 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4258 convert (tree_type, ffecom_expr (arg1)),
4259 convert (tree_type, ffecom_expr (arg2)));
4261 if (kt == FFEINFO_kindtypeREAL1)
4262 /* We used to call FFECOM_gfrtAMOD here. */
4263 gfrt = FFECOM_gfrtL_FMOD;
4264 else if (kt == FFEINFO_kindtypeREAL2)
4265 /* We used to call FFECOM_gfrtDMOD here. */
4266 gfrt = FFECOM_gfrtL_FMOD;
4269 case FFEINTRIN_impNINT:
4270 case FFEINTRIN_impIDNINT:
4272 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
4273 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4275 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4276 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4278 convert (ffecom_integer_type_node,
4279 ffecom_3 (COND_EXPR, arg1_type,
4281 (ffecom_2 (GE_EXPR, integer_type_node,
4284 ffecom_float_zero_))),
4285 ffecom_2 (PLUS_EXPR, arg1_type,
4288 ffecom_float_half_)),
4289 ffecom_2 (MINUS_EXPR, arg1_type,
4292 ffecom_float_half_))));
4295 case FFEINTRIN_impSIGN:
4296 case FFEINTRIN_impDSIGN:
4297 case FFEINTRIN_impISIGN:
4299 tree arg2_tree = ffecom_expr (arg2);
4303 (ffecom_1 (ABS_EXPR, tree_type,
4305 ffecom_expr (arg1))));
4307 = ffecom_3 (COND_EXPR, tree_type,
4309 (ffecom_2 (GE_EXPR, integer_type_node,
4311 convert (TREE_TYPE (arg2_tree),
4312 integer_zero_node))),
4314 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4315 /* Make sure SAVE_EXPRs get referenced early enough. */
4317 = ffecom_2 (COMPOUND_EXPR, tree_type,
4318 convert (void_type_node, saved_expr1),
4323 case FFEINTRIN_impSIN:
4324 case FFEINTRIN_impCDSIN:
4325 case FFEINTRIN_impCSIN:
4326 case FFEINTRIN_impDSIN:
4327 if (bt == FFEINFO_basictypeCOMPLEX)
4329 if (kt == FFEINFO_kindtypeREAL1)
4330 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4331 else if (kt == FFEINFO_kindtypeREAL2)
4332 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4336 case FFEINTRIN_impSINH:
4337 case FFEINTRIN_impDSINH:
4340 case FFEINTRIN_impSQRT:
4341 case FFEINTRIN_impCDSQRT:
4342 case FFEINTRIN_impCSQRT:
4343 case FFEINTRIN_impDSQRT:
4344 if (bt == FFEINFO_basictypeCOMPLEX)
4346 if (kt == FFEINFO_kindtypeREAL1)
4347 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4348 else if (kt == FFEINFO_kindtypeREAL2)
4349 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4353 case FFEINTRIN_impTAN:
4354 case FFEINTRIN_impDTAN:
4355 case FFEINTRIN_impTANH:
4356 case FFEINTRIN_impDTANH:
4359 case FFEINTRIN_impREALPART:
4360 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4361 arg1_type = TREE_TYPE (arg1_type);
4363 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4367 ffecom_1 (REALPART_EXPR, arg1_type,
4368 ffecom_expr (arg1)));
4370 case FFEINTRIN_impIAND:
4371 case FFEINTRIN_impAND:
4372 return ffecom_2 (BIT_AND_EXPR, tree_type,
4374 ffecom_expr (arg1)),
4376 ffecom_expr (arg2)));
4378 case FFEINTRIN_impIOR:
4379 case FFEINTRIN_impOR:
4380 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4382 ffecom_expr (arg1)),
4384 ffecom_expr (arg2)));
4386 case FFEINTRIN_impIEOR:
4387 case FFEINTRIN_impXOR:
4388 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4390 ffecom_expr (arg1)),
4392 ffecom_expr (arg2)));
4394 case FFEINTRIN_impLSHIFT:
4395 return ffecom_2 (LSHIFT_EXPR, tree_type,
4397 convert (integer_type_node,
4398 ffecom_expr (arg2)));
4400 case FFEINTRIN_impRSHIFT:
4401 return ffecom_2 (RSHIFT_EXPR, tree_type,
4403 convert (integer_type_node,
4404 ffecom_expr (arg2)));
4406 case FFEINTRIN_impNOT:
4407 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4409 case FFEINTRIN_impBIT_SIZE:
4410 return convert (tree_type, TYPE_SIZE (arg1_type));
4412 case FFEINTRIN_impBTEST:
4414 ffetargetLogical1 target_true;
4415 ffetargetLogical1 target_false;
4419 ffetarget_logical1 (&target_true, TRUE);
4420 ffetarget_logical1 (&target_false, FALSE);
4421 if (target_true == 1)
4422 true_tree = convert (tree_type, integer_one_node);
4424 true_tree = convert (tree_type, build_int_2 (target_true, 0));
4425 if (target_false == 0)
4426 false_tree = convert (tree_type, integer_zero_node);
4428 false_tree = convert (tree_type, build_int_2 (target_false, 0));
4431 ffecom_3 (COND_EXPR, tree_type,
4433 (ffecom_2 (EQ_EXPR, integer_type_node,
4434 ffecom_2 (BIT_AND_EXPR, arg1_type,
4436 ffecom_2 (LSHIFT_EXPR, arg1_type,
4439 convert (integer_type_node,
4440 ffecom_expr (arg2)))),
4442 integer_zero_node))),
4447 case FFEINTRIN_impIBCLR:
4449 ffecom_2 (BIT_AND_EXPR, tree_type,
4451 ffecom_1 (BIT_NOT_EXPR, tree_type,
4452 ffecom_2 (LSHIFT_EXPR, tree_type,
4455 convert (integer_type_node,
4456 ffecom_expr (arg2)))));
4458 case FFEINTRIN_impIBITS:
4460 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4461 ffecom_expr (arg3)));
4463 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4466 = ffecom_2 (BIT_AND_EXPR, tree_type,
4467 ffecom_2 (RSHIFT_EXPR, tree_type,
4469 convert (integer_type_node,
4470 ffecom_expr (arg2))),
4472 ffecom_2 (RSHIFT_EXPR, uns_type,
4473 ffecom_1 (BIT_NOT_EXPR,
4476 integer_zero_node)),
4477 ffecom_2 (MINUS_EXPR,
4479 TYPE_SIZE (uns_type),
4481 /* Fix up, because the RSHIFT_EXPR above can't shift over TYPE_SIZE. */
4483 = ffecom_3 (COND_EXPR, tree_type,
4485 (ffecom_2 (NE_EXPR, integer_type_node,
4487 integer_zero_node)),
4489 convert (tree_type, integer_zero_node));
4493 case FFEINTRIN_impIBSET:
4495 ffecom_2 (BIT_IOR_EXPR, tree_type,
4497 ffecom_2 (LSHIFT_EXPR, tree_type,
4498 convert (tree_type, integer_one_node),
4499 convert (integer_type_node,
4500 ffecom_expr (arg2))));
4502 case FFEINTRIN_impISHFT:
4504 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4505 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4506 ffecom_expr (arg2)));
4508 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4511 = ffecom_3 (COND_EXPR, tree_type,
4513 (ffecom_2 (GE_EXPR, integer_type_node,
4515 integer_zero_node)),
4516 ffecom_2 (LSHIFT_EXPR, tree_type,
4520 ffecom_2 (RSHIFT_EXPR, uns_type,
4521 convert (uns_type, arg1_tree),
4522 ffecom_1 (NEGATE_EXPR,
4525 /* Fix up, because {L|R}SHIFT_EXPR don't go over TYPE_SIZE bounds. */
4527 = ffecom_3 (COND_EXPR, tree_type,
4529 (ffecom_2 (NE_EXPR, integer_type_node,
4533 TYPE_SIZE (uns_type))),
4535 convert (tree_type, integer_zero_node));
4536 /* Make sure SAVE_EXPRs get referenced early enough. */
4538 = ffecom_2 (COMPOUND_EXPR, tree_type,
4539 convert (void_type_node, arg1_tree),
4540 ffecom_2 (COMPOUND_EXPR, tree_type,
4541 convert (void_type_node, arg2_tree),
4546 case FFEINTRIN_impISHFTC:
4548 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4549 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4550 ffecom_expr (arg2)));
4551 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4552 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4558 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4561 = ffecom_2 (LSHIFT_EXPR, tree_type,
4562 ffecom_1 (BIT_NOT_EXPR, tree_type,
4563 convert (tree_type, integer_zero_node)),
4565 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
4567 = ffecom_3 (COND_EXPR, tree_type,
4569 (ffecom_2 (NE_EXPR, integer_type_node,
4571 TYPE_SIZE (uns_type))),
4573 convert (tree_type, integer_zero_node));
4574 mask_arg1 = ffecom_save_tree (mask_arg1);
4576 = ffecom_2 (BIT_AND_EXPR, tree_type,
4578 ffecom_1 (BIT_NOT_EXPR, tree_type,
4580 masked_arg1 = ffecom_save_tree (masked_arg1);
4582 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4584 ffecom_2 (RSHIFT_EXPR, uns_type,
4585 convert (uns_type, masked_arg1),
4586 ffecom_1 (NEGATE_EXPR,
4589 ffecom_2 (LSHIFT_EXPR, tree_type,
4591 ffecom_2 (PLUS_EXPR, integer_type_node,
4595 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4596 ffecom_2 (LSHIFT_EXPR, tree_type,
4600 ffecom_2 (RSHIFT_EXPR, uns_type,
4601 convert (uns_type, masked_arg1),
4602 ffecom_2 (MINUS_EXPR,
4607 = ffecom_3 (COND_EXPR, tree_type,
4609 (ffecom_2 (LT_EXPR, integer_type_node,
4611 integer_zero_node)),
4615 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4616 ffecom_2 (BIT_AND_EXPR, tree_type,
4619 ffecom_2 (BIT_AND_EXPR, tree_type,
4620 ffecom_1 (BIT_NOT_EXPR, tree_type,
4624 = ffecom_3 (COND_EXPR, tree_type,
4626 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4627 ffecom_2 (EQ_EXPR, integer_type_node,
4632 ffecom_2 (EQ_EXPR, integer_type_node,
4634 integer_zero_node))),
4637 /* Make sure SAVE_EXPRs get referenced early enough. */
4639 = ffecom_2 (COMPOUND_EXPR, tree_type,
4640 convert (void_type_node, arg1_tree),
4641 ffecom_2 (COMPOUND_EXPR, tree_type,
4642 convert (void_type_node, arg2_tree),
4643 ffecom_2 (COMPOUND_EXPR, tree_type,
4644 convert (void_type_node,
4646 ffecom_2 (COMPOUND_EXPR, tree_type,
4647 convert (void_type_node,
4651 = ffecom_2 (COMPOUND_EXPR, tree_type,
4652 convert (void_type_node,
4658 case FFEINTRIN_impLOC:
4660 tree arg1_tree = ffecom_expr (arg1);
4663 = convert (tree_type,
4664 ffecom_1 (ADDR_EXPR,
4665 build_pointer_type (TREE_TYPE (arg1_tree)),
4670 case FFEINTRIN_impMVBITS:
4675 ffebld arg4 = ffebld_head (ffebld_trail (list));
4678 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4682 tree arg5_plus_arg3;
4684 arg2_tree = convert (integer_type_node,
4685 ffecom_expr (arg2));
4686 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4687 ffecom_expr (arg3)));
4688 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
4689 arg4_type = TREE_TYPE (arg4_tree);
4691 arg1_tree = ffecom_save_tree (convert (arg4_type,
4692 ffecom_expr (arg1)));
4694 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4695 ffecom_expr (arg5)));
4698 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4699 ffecom_2 (BIT_AND_EXPR, arg4_type,
4700 ffecom_2 (RSHIFT_EXPR, arg4_type,
4703 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4704 ffecom_2 (LSHIFT_EXPR, arg4_type,
4705 ffecom_1 (BIT_NOT_EXPR,
4709 integer_zero_node)),
4713 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4717 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4718 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4720 integer_zero_node)),
4722 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
4724 = ffecom_3 (COND_EXPR, arg4_type,
4726 (ffecom_2 (NE_EXPR, integer_type_node,
4728 convert (TREE_TYPE (arg5_plus_arg3),
4729 TYPE_SIZE (arg4_type)))),
4731 convert (arg4_type, integer_zero_node));
4733 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4735 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4737 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4738 ffecom_2 (LSHIFT_EXPR, arg4_type,
4739 ffecom_1 (BIT_NOT_EXPR,
4743 integer_zero_node)),
4746 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4749 /* Fix up (twice), because LSHIFT_EXPR above
4750 can't shift over TYPE_SIZE. */
4752 = ffecom_3 (COND_EXPR, arg4_type,
4754 (ffecom_2 (NE_EXPR, integer_type_node,
4756 convert (TREE_TYPE (arg3_tree),
4757 integer_zero_node))),
4761 = ffecom_3 (COND_EXPR, arg4_type,
4763 (ffecom_2 (NE_EXPR, integer_type_node,
4765 convert (TREE_TYPE (arg3_tree),
4766 TYPE_SIZE (arg4_type)))),
4770 = ffecom_2s (MODIFY_EXPR, void_type_node,
4773 /* Make sure SAVE_EXPRs get referenced early enough. */
4775 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4777 ffecom_2 (COMPOUND_EXPR, void_type_node,
4779 ffecom_2 (COMPOUND_EXPR, void_type_node,
4781 ffecom_2 (COMPOUND_EXPR, void_type_node,
4785 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4792 case FFEINTRIN_impDERF:
4793 case FFEINTRIN_impERF:
4794 case FFEINTRIN_impDERFC:
4795 case FFEINTRIN_impERFC:
4798 case FFEINTRIN_impIARGC:
4799 /* extern int xargc; i__1 = xargc - 1; */
4800 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4802 convert (TREE_TYPE (ffecom_tree_xargc_),
4806 case FFEINTRIN_impSIGNAL_func:
4807 case FFEINTRIN_impSIGNAL_subr:
4813 arg1_tree = convert (ffecom_f2c_integer_type_node,
4814 ffecom_expr (arg1));
4815 arg1_tree = ffecom_1 (ADDR_EXPR,
4816 build_pointer_type (TREE_TYPE (arg1_tree)),
4819 /* Pass procedure as a pointer to it, anything else by value. */
4820 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4821 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4823 arg2_tree = ffecom_ptr_to_expr (arg2);
4824 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4828 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4830 arg3_tree = NULL_TREE;
4832 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4833 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4834 TREE_CHAIN (arg1_tree) = arg2_tree;
4837 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4838 ffecom_gfrt_kindtype (gfrt),
4840 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4844 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4845 ffebld_nonter_hook (expr));
4847 if (arg3_tree != NULL_TREE)
4849 = ffecom_modify (NULL_TREE, arg3_tree,
4850 convert (TREE_TYPE (arg3_tree),
4855 case FFEINTRIN_impALARM:
4861 arg1_tree = convert (ffecom_f2c_integer_type_node,
4862 ffecom_expr (arg1));
4863 arg1_tree = ffecom_1 (ADDR_EXPR,
4864 build_pointer_type (TREE_TYPE (arg1_tree)),
4867 /* Pass procedure as a pointer to it, anything else by value. */
4868 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4869 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4871 arg2_tree = ffecom_ptr_to_expr (arg2);
4872 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4876 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4878 arg3_tree = NULL_TREE;
4880 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4881 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4882 TREE_CHAIN (arg1_tree) = arg2_tree;
4885 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4886 ffecom_gfrt_kindtype (gfrt),
4890 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4891 ffebld_nonter_hook (expr));
4893 if (arg3_tree != NULL_TREE)
4895 = ffecom_modify (NULL_TREE, arg3_tree,
4896 convert (TREE_TYPE (arg3_tree),
4901 case FFEINTRIN_impCHDIR_subr:
4902 case FFEINTRIN_impFDATE_subr:
4903 case FFEINTRIN_impFGET_subr:
4904 case FFEINTRIN_impFPUT_subr:
4905 case FFEINTRIN_impGETCWD_subr:
4906 case FFEINTRIN_impHOSTNM_subr:
4907 case FFEINTRIN_impSYSTEM_subr:
4908 case FFEINTRIN_impUNLINK_subr:
4910 tree arg1_len = integer_zero_node;
4914 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4917 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
4919 arg2_tree = NULL_TREE;
4921 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4922 arg1_len = build_tree_list (NULL_TREE, arg1_len);
4923 TREE_CHAIN (arg1_tree) = arg1_len;
4926 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4927 ffecom_gfrt_kindtype (gfrt),
4931 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4932 ffebld_nonter_hook (expr));
4934 if (arg2_tree != NULL_TREE)
4936 = ffecom_modify (NULL_TREE, arg2_tree,
4937 convert (TREE_TYPE (arg2_tree),
4942 case FFEINTRIN_impEXIT:
4946 expr_tree = build_tree_list (NULL_TREE,
4947 ffecom_1 (ADDR_EXPR,
4949 (ffecom_integer_type_node),
4950 integer_zero_node));
4953 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4954 ffecom_gfrt_kindtype (gfrt),
4958 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4959 ffebld_nonter_hook (expr));
4961 case FFEINTRIN_impFLUSH:
4963 gfrt = FFECOM_gfrtFLUSH;
4965 gfrt = FFECOM_gfrtFLUSH1;
4968 case FFEINTRIN_impCHMOD_subr:
4969 case FFEINTRIN_impLINK_subr:
4970 case FFEINTRIN_impRENAME_subr:
4971 case FFEINTRIN_impSYMLNK_subr:
4973 tree arg1_len = integer_zero_node;
4975 tree arg2_len = integer_zero_node;
4979 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4980 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
4982 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4984 arg3_tree = NULL_TREE;
4986 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4987 arg1_len = build_tree_list (NULL_TREE, arg1_len);
4988 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4989 arg2_len = build_tree_list (NULL_TREE, arg2_len);
4990 TREE_CHAIN (arg1_tree) = arg2_tree;
4991 TREE_CHAIN (arg2_tree) = arg1_len;
4992 TREE_CHAIN (arg1_len) = arg2_len;
4993 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4994 ffecom_gfrt_kindtype (gfrt),
4998 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4999 ffebld_nonter_hook (expr));
5000 if (arg3_tree != NULL_TREE)
5001 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5002 convert (TREE_TYPE (arg3_tree),
5007 case FFEINTRIN_impLSTAT_subr:
5008 case FFEINTRIN_impSTAT_subr:
5010 tree arg1_len = integer_zero_node;
5015 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5017 arg2_tree = ffecom_ptr_to_expr (arg2);
5020 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5022 arg3_tree = NULL_TREE;
5024 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5025 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5026 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5027 TREE_CHAIN (arg1_tree) = arg2_tree;
5028 TREE_CHAIN (arg2_tree) = arg1_len;
5029 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5030 ffecom_gfrt_kindtype (gfrt),
5034 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5035 ffebld_nonter_hook (expr));
5036 if (arg3_tree != NULL_TREE)
5037 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5038 convert (TREE_TYPE (arg3_tree),
5043 case FFEINTRIN_impFGETC_subr:
5044 case FFEINTRIN_impFPUTC_subr:
5048 tree arg2_len = integer_zero_node;
5051 arg1_tree = convert (ffecom_f2c_integer_type_node,
5052 ffecom_expr (arg1));
5053 arg1_tree = ffecom_1 (ADDR_EXPR,
5054 build_pointer_type (TREE_TYPE (arg1_tree)),
5057 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5059 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5061 arg3_tree = NULL_TREE;
5063 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5064 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5065 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5066 TREE_CHAIN (arg1_tree) = arg2_tree;
5067 TREE_CHAIN (arg2_tree) = arg2_len;
5069 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5070 ffecom_gfrt_kindtype (gfrt),
5074 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5075 ffebld_nonter_hook (expr));
5076 if (arg3_tree != NULL_TREE)
5077 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5078 convert (TREE_TYPE (arg3_tree),
5083 case FFEINTRIN_impFSTAT_subr:
5089 arg1_tree = convert (ffecom_f2c_integer_type_node,
5090 ffecom_expr (arg1));
5091 arg1_tree = ffecom_1 (ADDR_EXPR,
5092 build_pointer_type (TREE_TYPE (arg1_tree)),
5095 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
5096 ffecom_ptr_to_expr (arg2));
5099 arg3_tree = NULL_TREE;
5101 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5103 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5104 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5105 TREE_CHAIN (arg1_tree) = arg2_tree;
5106 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5107 ffecom_gfrt_kindtype (gfrt),
5111 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5112 ffebld_nonter_hook (expr));
5113 if (arg3_tree != NULL_TREE) {
5114 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5115 convert (TREE_TYPE (arg3_tree),
5121 case FFEINTRIN_impKILL_subr:
5127 arg1_tree = convert (ffecom_f2c_integer_type_node,
5128 ffecom_expr (arg1));
5129 arg1_tree = ffecom_1 (ADDR_EXPR,
5130 build_pointer_type (TREE_TYPE (arg1_tree)),
5133 arg2_tree = convert (ffecom_f2c_integer_type_node,
5134 ffecom_expr (arg2));
5135 arg2_tree = ffecom_1 (ADDR_EXPR,
5136 build_pointer_type (TREE_TYPE (arg2_tree)),
5140 arg3_tree = NULL_TREE;
5142 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5144 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5145 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5146 TREE_CHAIN (arg1_tree) = arg2_tree;
5147 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5148 ffecom_gfrt_kindtype (gfrt),
5152 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5153 ffebld_nonter_hook (expr));
5154 if (arg3_tree != NULL_TREE) {
5155 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5156 convert (TREE_TYPE (arg3_tree),
5162 case FFEINTRIN_impCTIME_subr:
5163 case FFEINTRIN_impTTYNAM_subr:
5165 tree arg1_len = integer_zero_node;
5169 arg1_tree = ffecom_arg_ptr_to_expr (arg2, &arg1_len);
5171 arg2_tree = convert (((codegen_imp == FFEINTRIN_impCTIME_subr) ?
5172 ffecom_f2c_longint_type_node :
5173 ffecom_f2c_integer_type_node),
5174 ffecom_expr (arg1));
5175 arg2_tree = ffecom_1 (ADDR_EXPR,
5176 build_pointer_type (TREE_TYPE (arg2_tree)),
5179 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5180 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5181 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5182 TREE_CHAIN (arg1_len) = arg2_tree;
5183 TREE_CHAIN (arg1_tree) = arg1_len;
5186 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5187 ffecom_gfrt_kindtype (gfrt),
5191 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5192 ffebld_nonter_hook (expr));
5193 TREE_SIDE_EFFECTS (expr_tree) = 1;
5197 case FFEINTRIN_impIRAND:
5198 case FFEINTRIN_impRAND:
5199 /* Arg defaults to 0 (normal random case) */
5204 arg1_tree = ffecom_integer_zero_node;
5206 arg1_tree = ffecom_expr (arg1);
5207 arg1_tree = convert (ffecom_f2c_integer_type_node,
5209 arg1_tree = ffecom_1 (ADDR_EXPR,
5210 build_pointer_type (TREE_TYPE (arg1_tree)),
5212 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5214 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5215 ffecom_gfrt_kindtype (gfrt),
5217 ((codegen_imp == FFEINTRIN_impIRAND) ?
5218 ffecom_f2c_integer_type_node :
5219 ffecom_f2c_real_type_node),
5221 dest_tree, dest, dest_used,
5223 ffebld_nonter_hook (expr));
5227 case FFEINTRIN_impFTELL_subr:
5228 case FFEINTRIN_impUMASK_subr:
5233 arg1_tree = convert (ffecom_f2c_integer_type_node,
5234 ffecom_expr (arg1));
5235 arg1_tree = ffecom_1 (ADDR_EXPR,
5236 build_pointer_type (TREE_TYPE (arg1_tree)),
5240 arg2_tree = NULL_TREE;
5242 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5244 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5245 ffecom_gfrt_kindtype (gfrt),
5248 build_tree_list (NULL_TREE, arg1_tree),
5249 NULL_TREE, NULL, NULL, NULL_TREE,
5251 ffebld_nonter_hook (expr));
5252 if (arg2_tree != NULL_TREE) {
5253 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5254 convert (TREE_TYPE (arg2_tree),
5260 case FFEINTRIN_impCPU_TIME:
5261 case FFEINTRIN_impSECOND_subr:
5265 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5268 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5269 ffecom_gfrt_kindtype (gfrt),
5273 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5274 ffebld_nonter_hook (expr));
5277 = ffecom_modify (NULL_TREE, arg1_tree,
5278 convert (TREE_TYPE (arg1_tree),
5283 case FFEINTRIN_impDTIME_subr:
5284 case FFEINTRIN_impETIME_subr:
5289 result_tree = ffecom_expr_w (NULL_TREE, arg2);
5291 arg1_tree = ffecom_ptr_to_expr (arg1);
5293 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5294 ffecom_gfrt_kindtype (gfrt),
5297 build_tree_list (NULL_TREE, arg1_tree),
5298 NULL_TREE, NULL, NULL, NULL_TREE,
5300 ffebld_nonter_hook (expr));
5301 expr_tree = ffecom_modify (NULL_TREE, result_tree,
5302 convert (TREE_TYPE (result_tree),
5307 /* Straightforward calls of libf2c routines: */
5308 case FFEINTRIN_impABORT:
5309 case FFEINTRIN_impACCESS:
5310 case FFEINTRIN_impBESJ0:
5311 case FFEINTRIN_impBESJ1:
5312 case FFEINTRIN_impBESJN:
5313 case FFEINTRIN_impBESY0:
5314 case FFEINTRIN_impBESY1:
5315 case FFEINTRIN_impBESYN:
5316 case FFEINTRIN_impCHDIR_func:
5317 case FFEINTRIN_impCHMOD_func:
5318 case FFEINTRIN_impDATE:
5319 case FFEINTRIN_impDATE_AND_TIME:
5320 case FFEINTRIN_impDBESJ0:
5321 case FFEINTRIN_impDBESJ1:
5322 case FFEINTRIN_impDBESJN:
5323 case FFEINTRIN_impDBESY0:
5324 case FFEINTRIN_impDBESY1:
5325 case FFEINTRIN_impDBESYN:
5326 case FFEINTRIN_impDTIME_func:
5327 case FFEINTRIN_impETIME_func:
5328 case FFEINTRIN_impFGETC_func:
5329 case FFEINTRIN_impFGET_func:
5330 case FFEINTRIN_impFNUM:
5331 case FFEINTRIN_impFPUTC_func:
5332 case FFEINTRIN_impFPUT_func:
5333 case FFEINTRIN_impFSEEK:
5334 case FFEINTRIN_impFSTAT_func:
5335 case FFEINTRIN_impFTELL_func:
5336 case FFEINTRIN_impGERROR:
5337 case FFEINTRIN_impGETARG:
5338 case FFEINTRIN_impGETCWD_func:
5339 case FFEINTRIN_impGETENV:
5340 case FFEINTRIN_impGETGID:
5341 case FFEINTRIN_impGETLOG:
5342 case FFEINTRIN_impGETPID:
5343 case FFEINTRIN_impGETUID:
5344 case FFEINTRIN_impGMTIME:
5345 case FFEINTRIN_impHOSTNM_func:
5346 case FFEINTRIN_impIDATE_unix:
5347 case FFEINTRIN_impIDATE_vxt:
5348 case FFEINTRIN_impIERRNO:
5349 case FFEINTRIN_impISATTY:
5350 case FFEINTRIN_impITIME:
5351 case FFEINTRIN_impKILL_func:
5352 case FFEINTRIN_impLINK_func:
5353 case FFEINTRIN_impLNBLNK:
5354 case FFEINTRIN_impLSTAT_func:
5355 case FFEINTRIN_impLTIME:
5356 case FFEINTRIN_impMCLOCK8:
5357 case FFEINTRIN_impMCLOCK:
5358 case FFEINTRIN_impPERROR:
5359 case FFEINTRIN_impRENAME_func:
5360 case FFEINTRIN_impSECNDS:
5361 case FFEINTRIN_impSECOND_func:
5362 case FFEINTRIN_impSLEEP:
5363 case FFEINTRIN_impSRAND:
5364 case FFEINTRIN_impSTAT_func:
5365 case FFEINTRIN_impSYMLNK_func:
5366 case FFEINTRIN_impSYSTEM_CLOCK:
5367 case FFEINTRIN_impSYSTEM_func:
5368 case FFEINTRIN_impTIME8:
5369 case FFEINTRIN_impTIME_unix:
5370 case FFEINTRIN_impTIME_vxt:
5371 case FFEINTRIN_impUMASK_func:
5372 case FFEINTRIN_impUNLINK_func:
5375 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5376 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5377 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5378 case FFEINTRIN_impNONE:
5379 case FFEINTRIN_imp: /* Hush up gcc warning. */
5380 fprintf (stderr, "No %s implementation.\n",
5381 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5382 assert ("unimplemented intrinsic" == NULL);
5383 return error_mark_node;
5386 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5388 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5389 ffebld_right (expr));
5391 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5392 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5394 expr_tree, dest_tree, dest, dest_used,
5396 ffebld_nonter_hook (expr));
5398 /* See bottom of this file for f2c transforms used to determine
5399 many of the above implementations. The info seems to confuse
5400 Emacs's C mode indentation, which is why it's been moved to
5401 the bottom of this source file. */
5404 /* For power (exponentiation) where right-hand operand is type INTEGER,
5405 generate in-line code to do it the fast way (which, if the operand
5406 is a constant, might just mean a series of multiplies). */
5409 ffecom_expr_power_integer_ (ffebld expr)
5411 tree l = ffecom_expr (ffebld_left (expr));
5412 tree r = ffecom_expr (ffebld_right (expr));
5413 tree ltype = TREE_TYPE (l);
5414 tree rtype = TREE_TYPE (r);
5415 tree result = NULL_TREE;
5417 if (l == error_mark_node
5418 || r == error_mark_node)
5419 return error_mark_node;
5421 if (TREE_CODE (r) == INTEGER_CST)
5423 int sgn = tree_int_cst_sgn (r);
5426 return convert (ltype, integer_one_node);
5428 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5431 /* Reciprocal of integer is either 0, -1, or 1, so after
5432 calculating that (which we leave to the back end to do
5433 or not do optimally), don't bother with any multiplying. */
5435 result = ffecom_tree_divide_ (ltype,
5436 convert (ltype, integer_one_node),
5438 NULL_TREE, NULL, NULL, NULL_TREE);
5439 r = ffecom_1 (NEGATE_EXPR,
5442 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5443 result = ffecom_1 (ABS_EXPR, rtype,
5447 /* Generate appropriate series of multiplies, preceded
5448 by divide if the exponent is negative. */
5454 l = ffecom_tree_divide_ (ltype,
5455 convert (ltype, integer_one_node),
5457 NULL_TREE, NULL, NULL,
5458 ffebld_nonter_hook (expr));
5459 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5460 assert (TREE_CODE (r) == INTEGER_CST);
5462 if (tree_int_cst_sgn (r) < 0)
5463 { /* The "most negative" number. */
5464 r = ffecom_1 (NEGATE_EXPR, rtype,
5465 ffecom_2 (RSHIFT_EXPR, rtype,
5469 l = ffecom_2 (MULT_EXPR, ltype,
5477 if (TREE_INT_CST_LOW (r) & 1)
5479 if (result == NULL_TREE)
5482 result = ffecom_2 (MULT_EXPR, ltype,
5487 r = ffecom_2 (RSHIFT_EXPR, rtype,
5490 if (integer_zerop (r))
5492 assert (TREE_CODE (r) == INTEGER_CST);
5495 l = ffecom_2 (MULT_EXPR, ltype,
5502 /* Though rhs isn't a constant, in-line code cannot be expanded
5503 while transforming dummies
5504 because the back end cannot be easily convinced to generate
5505 stores (MODIFY_EXPR), handle temporaries, and so on before
5506 all the appropriate rtx's have been generated for things like
5507 dummy args referenced in rhs -- which doesn't happen until
5508 store_parm_decls() is called (expand_function_start, I believe,
5509 does the actual rtx-stuffing of PARM_DECLs).
5511 So, in this case, let the caller generate the call to the
5512 run-time-library function to evaluate the power for us. */
5514 if (ffecom_transform_only_dummies_)
5517 /* Right-hand operand not a constant, expand in-line code to figure
5518 out how to do the multiplies, &c.
5520 The returned expression is expressed this way in GNU C, where l and
5523 ({ typeof (r) rtmp = r;
5524 typeof (l) ltmp = l;
5531 if ((basetypeof (l) == basetypeof (int))
5534 result = ((typeof (l)) 1) / ltmp;
5535 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5541 if ((basetypeof (l) != basetypeof (int))
5544 ltmp = ((typeof (l)) 1) / ltmp;
5548 rtmp = -(rtmp >> 1);
5556 if ((rtmp >>= 1) == 0)
5565 Note that some of the above is compile-time collapsable, such as
5566 the first part of the if statements that checks the base type of
5567 l against int. The if statements are phrased that way to suggest
5568 an easy way to generate the if/else constructs here, knowing that
5569 the back end should (and probably does) eliminate the resulting
5570 dead code (either the int case or the non-int case), something
5571 it couldn't do without the redundant phrasing, requiring explicit
5572 dead-code elimination here, which would be kind of difficult to
5579 tree basetypeof_l_is_int;
5584 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5586 se = expand_start_stmt_expr ();
5588 ffecom_start_compstmt ();
5591 rtmp = ffecom_make_tempvar ("power_r", rtype,
5592 FFETARGET_charactersizeNONE, -1);
5593 ltmp = ffecom_make_tempvar ("power_l", ltype,
5594 FFETARGET_charactersizeNONE, -1);
5595 result = ffecom_make_tempvar ("power_res", ltype,
5596 FFETARGET_charactersizeNONE, -1);
5597 if (TREE_CODE (ltype) == COMPLEX_TYPE
5598 || TREE_CODE (ltype) == RECORD_TYPE)
5599 divide = ffecom_make_tempvar ("power_div", ltype,
5600 FFETARGET_charactersizeNONE, -1);
5607 hook = ffebld_nonter_hook (expr);
5609 assert (TREE_CODE (hook) == TREE_VEC);
5610 assert (TREE_VEC_LENGTH (hook) == 4);
5611 rtmp = TREE_VEC_ELT (hook, 0);
5612 ltmp = TREE_VEC_ELT (hook, 1);
5613 result = TREE_VEC_ELT (hook, 2);
5614 divide = TREE_VEC_ELT (hook, 3);
5615 if (TREE_CODE (ltype) == COMPLEX_TYPE
5616 || TREE_CODE (ltype) == RECORD_TYPE)
5623 expand_expr_stmt (ffecom_modify (void_type_node,
5626 expand_expr_stmt (ffecom_modify (void_type_node,
5629 expand_start_cond (ffecom_truth_value
5630 (ffecom_2 (EQ_EXPR, integer_type_node,
5632 convert (rtype, integer_zero_node))),
5634 expand_expr_stmt (ffecom_modify (void_type_node,
5636 convert (ltype, integer_one_node)));
5637 expand_start_else ();
5638 if (! integer_zerop (basetypeof_l_is_int))
5640 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5643 integer_zero_node)),
5645 expand_expr_stmt (ffecom_modify (void_type_node,
5649 convert (ltype, integer_one_node),
5651 NULL_TREE, NULL, NULL,
5653 expand_start_cond (ffecom_truth_value
5654 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5655 ffecom_2 (LT_EXPR, integer_type_node,
5658 integer_zero_node)),
5659 ffecom_2 (EQ_EXPR, integer_type_node,
5660 ffecom_2 (BIT_AND_EXPR,
5662 ffecom_1 (NEGATE_EXPR,
5668 integer_zero_node)))),
5670 expand_expr_stmt (ffecom_modify (void_type_node,
5672 ffecom_1 (NEGATE_EXPR,
5676 expand_start_else ();
5678 expand_expr_stmt (ffecom_modify (void_type_node,
5680 convert (ltype, integer_one_node)));
5681 expand_start_cond (ffecom_truth_value
5682 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5683 ffecom_truth_value_invert
5684 (basetypeof_l_is_int),
5685 ffecom_2 (LT_EXPR, integer_type_node,
5688 integer_zero_node)))),
5690 expand_expr_stmt (ffecom_modify (void_type_node,
5694 convert (ltype, integer_one_node),
5696 NULL_TREE, NULL, NULL,
5698 expand_expr_stmt (ffecom_modify (void_type_node,
5700 ffecom_1 (NEGATE_EXPR, rtype,
5702 expand_start_cond (ffecom_truth_value
5703 (ffecom_2 (LT_EXPR, integer_type_node,
5705 convert (rtype, integer_zero_node))),
5707 expand_expr_stmt (ffecom_modify (void_type_node,
5709 ffecom_1 (NEGATE_EXPR, rtype,
5710 ffecom_2 (RSHIFT_EXPR,
5713 integer_one_node))));
5714 expand_expr_stmt (ffecom_modify (void_type_node,
5716 ffecom_2 (MULT_EXPR, ltype,
5721 expand_start_loop (1);
5722 expand_start_cond (ffecom_truth_value
5723 (ffecom_2 (BIT_AND_EXPR, rtype,
5725 convert (rtype, integer_one_node))),
5727 expand_expr_stmt (ffecom_modify (void_type_node,
5729 ffecom_2 (MULT_EXPR, ltype,
5733 expand_exit_loop_if_false (NULL,
5735 (ffecom_modify (rtype,
5737 ffecom_2 (RSHIFT_EXPR,
5740 integer_one_node))));
5741 expand_expr_stmt (ffecom_modify (void_type_node,
5743 ffecom_2 (MULT_EXPR, ltype,
5748 if (!integer_zerop (basetypeof_l_is_int))
5750 expand_expr_stmt (result);
5752 t = ffecom_end_compstmt ();
5754 result = expand_end_stmt_expr (se);
5756 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5758 if (TREE_CODE (t) == BLOCK)
5760 /* Make a BIND_EXPR for the BLOCK already made. */
5761 result = build (BIND_EXPR, TREE_TYPE (result),
5762 NULL_TREE, result, t);
5763 /* Remove the block from the tree at this point.
5764 It gets put back at the proper place
5765 when the BIND_EXPR is expanded. */
5775 /* ffecom_expr_transform_ -- Transform symbols in expr
5777 ffebld expr; // FFE expression.
5778 ffecom_expr_transform_ (expr);
5780 Recursive descent on expr while transforming any untransformed SYMTERs. */
5783 ffecom_expr_transform_ (ffebld expr)
5793 switch (ffebld_op (expr))
5795 case FFEBLD_opSYMTER:
5796 s = ffebld_symter (expr);
5797 t = ffesymbol_hook (s).decl_tree;
5798 if ((t == NULL_TREE)
5799 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5800 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5801 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5803 s = ffecom_sym_transform_ (s);
5804 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5807 break; /* Ok if (t == NULL) here. */
5810 ffecom_expr_transform_ (ffebld_head (expr));
5811 expr = ffebld_trail (expr);
5812 goto tail_recurse; /* :::::::::::::::::::: */
5818 switch (ffebld_arity (expr))
5821 ffecom_expr_transform_ (ffebld_left (expr));
5822 expr = ffebld_right (expr);
5823 goto tail_recurse; /* :::::::::::::::::::: */
5826 expr = ffebld_left (expr);
5827 goto tail_recurse; /* :::::::::::::::::::: */
5836 /* Make a type based on info in live f2c.h file. */
5839 ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5843 case FFECOM_f2ccodeCHAR:
5844 *type = make_signed_type (CHAR_TYPE_SIZE);
5847 case FFECOM_f2ccodeSHORT:
5848 *type = make_signed_type (SHORT_TYPE_SIZE);
5851 case FFECOM_f2ccodeINT:
5852 *type = make_signed_type (INT_TYPE_SIZE);
5855 case FFECOM_f2ccodeLONG:
5856 *type = make_signed_type (LONG_TYPE_SIZE);
5859 case FFECOM_f2ccodeLONGLONG:
5860 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
5863 case FFECOM_f2ccodeCHARPTR:
5864 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
5865 ? signed_char_type_node
5866 : unsigned_char_type_node);
5869 case FFECOM_f2ccodeFLOAT:
5870 *type = make_node (REAL_TYPE);
5871 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
5872 layout_type (*type);
5875 case FFECOM_f2ccodeDOUBLE:
5876 *type = make_node (REAL_TYPE);
5877 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
5878 layout_type (*type);
5881 case FFECOM_f2ccodeLONGDOUBLE:
5882 *type = make_node (REAL_TYPE);
5883 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
5884 layout_type (*type);
5887 case FFECOM_f2ccodeTWOREALS:
5888 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
5891 case FFECOM_f2ccodeTWODOUBLEREALS:
5892 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
5896 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
5897 *type = error_mark_node;
5901 pushdecl (build_decl (TYPE_DECL,
5902 ffecom_get_invented_identifier ("__g77_f2c_%s", name),
5906 /* Set the f2c list-directed-I/O code for whatever (integral) type has the
5910 ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
5916 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
5917 if ((t = ffecom_tree_type[bt][j]) != NULL_TREE
5918 && compare_tree_int (TYPE_SIZE (t), size) == 0)
5920 assert (code != -1);
5921 ffecom_f2c_typecode_[bt][j] = code;
5926 /* Finish up globals after doing all program units in file
5928 Need to handle only uninitialized COMMON areas. */
5931 ffecom_finish_global_ (ffeglobal global)
5937 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
5940 if (ffeglobal_common_init (global))
5943 cbt = ffeglobal_hook (global);
5944 if ((cbt == NULL_TREE)
5945 || !ffeglobal_common_have_size (global))
5946 return global; /* No need to make common, never ref'd. */
5948 DECL_EXTERNAL (cbt) = 0;
5950 /* Give the array a size now. */
5952 size = build_int_2 ((ffeglobal_common_size (global)
5953 + ffeglobal_common_pad (global)) - 1,
5956 cbtype = TREE_TYPE (cbt);
5957 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
5960 if (!TREE_TYPE (size))
5961 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
5962 layout_type (cbtype);
5964 cbt = start_decl (cbt, FALSE);
5965 assert (cbt == ffeglobal_hook (global));
5967 finish_decl (cbt, NULL_TREE, FALSE);
5972 /* Finish up any untransformed symbols. */
5975 ffecom_finish_symbol_transform_ (ffesymbol s)
5977 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
5980 /* It's easy to know to transform an untransformed symbol, to make sure
5981 we put out debugging info for it. But COMMON variables, unlike
5982 EQUIVALENCE ones, aren't given declarations in addition to the
5983 tree expressions that specify offsets, because COMMON variables
5984 can be referenced in the outer scope where only dummy arguments
5985 (PARM_DECLs) should really be seen. To be safe, just don't do any
5986 VAR_DECLs for COMMON variables when we transform them for real
5987 use, and therefore we do all the VAR_DECL creating here. */
5989 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
5991 if (ffesymbol_kind (s) != FFEINFO_kindNONE
5992 || (ffesymbol_where (s) != FFEINFO_whereNONE
5993 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
5994 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
5995 /* Not transformed, and not CHARACTER*(*), and not a dummy
5996 argument, which can happen only if the entry point names
5997 it "rides in on" are all invalidated for other reasons. */
5998 s = ffecom_sym_transform_ (s);
6001 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
6002 && (ffesymbol_hook (s).decl_tree != error_mark_node))
6004 /* This isn't working, at least for dbxout. The .s file looks
6005 okay to me (burley), but in gdb 4.9 at least, the variables
6006 appear to reside somewhere outside of the common area, so
6007 it doesn't make sense to mislead anyone by generating the info
6008 on those variables until this is fixed. NOTE: Same problem
6009 with EQUIVALENCE, sadly...see similar #if later. */
6010 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6011 ffesymbol_storage (s));
6017 /* Append underscore(s) to name before calling get_identifier. "us"
6018 is nonzero if the name already contains an underscore and thus
6019 needs two underscores appended. */
6022 ffecom_get_appended_identifier_ (char us, const char *name)
6028 newname = xmalloc ((i = strlen (name)) + 1
6029 + ffe_is_underscoring ()
6031 memcpy (newname, name, i);
6033 newname[i + us] = '_';
6034 newname[i + 1 + us] = '\0';
6035 id = get_identifier (newname);
6042 /* Decide whether to append underscore to name before calling
6046 ffecom_get_external_identifier_ (ffesymbol s)
6049 const char *name = ffesymbol_text (s);
6051 /* If name is a built-in name, just return it as is. */
6053 if (!ffe_is_underscoring ()
6054 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6055 #if FFETARGET_isENFORCED_MAIN_NAME
6056 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
6058 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6060 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6061 return get_identifier (name);
6063 us = ffe_is_second_underscore ()
6064 ? (strchr (name, '_') != NULL)
6067 return ffecom_get_appended_identifier_ (us, name);
6070 /* Decide whether to append underscore to internal name before calling
6073 This is for non-external, top-function-context names only. Transform
6074 identifier so it doesn't conflict with the transformed result
6075 of using a _different_ external name. E.g. if "CALL FOO" is
6076 transformed into "FOO_();", then the variable in "FOO_ = 3"
6077 must be transformed into something that does not conflict, since
6078 these two things should be independent.
6080 The transformation is as follows. If the name does not contain
6081 an underscore, there is no possible conflict, so just return.
6082 If the name does contain an underscore, then transform it just
6083 like we transform an external identifier. */
6086 ffecom_get_identifier_ (const char *name)
6088 /* If name does not contain an underscore, just return it as is. */
6090 if (!ffe_is_underscoring ()
6091 || (strchr (name, '_') == NULL))
6092 return get_identifier (name);
6094 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6098 /* ffecom_gen_sfuncdef_ -- Generate definition of statement function
6101 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6102 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6103 ffesymbol_kindtype(s));
6105 Call after setting up containing function and getting trees for all
6109 ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
6111 ffebld expr = ffesymbol_sfexpr (s);
6115 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6116 static bool recurse = FALSE;
6117 int old_lineno = lineno;
6118 const char *old_input_filename = input_filename;
6120 ffecom_nested_entry_ = s;
6122 /* For now, we don't have a handy pointer to where the sfunc is actually
6123 defined, though that should be easy to add to an ffesymbol. (The
6124 token/where info available might well point to the place where the type
6125 of the sfunc is declared, especially if that precedes the place where
6126 the sfunc itself is defined, which is typically the case.) We should
6127 put out a null pointer rather than point somewhere wrong, but I want to
6128 see how it works at this point. */
6130 input_filename = ffesymbol_where_filename (s);
6131 lineno = ffesymbol_where_filelinenum (s);
6133 /* Pretransform the expression so any newly discovered things belong to the
6134 outer program unit, not to the statement function. */
6136 ffecom_expr_transform_ (expr);
6138 /* Make sure no recursive invocation of this fn (a specific case of failing
6139 to pretransform an sfunc's expression, i.e. where its expression
6140 references another untransformed sfunc) happens. */
6145 push_f_function_context ();
6148 type = void_type_node;
6151 type = ffecom_tree_type[bt][kt];
6152 if (type == NULL_TREE)
6153 type = integer_type_node; /* _sym_exec_transition reports
6157 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6158 build_function_type (type, NULL_TREE),
6159 1, /* nested/inline */
6160 0); /* TREE_PUBLIC */
6162 /* We don't worry about COMPLEX return values here, because this is
6163 entirely internal to our code, and gcc has the ability to return COMPLEX
6164 directly as a value. */
6167 { /* Prepend arg for where result goes. */
6170 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6172 result = ffecom_get_invented_identifier ("__g77_%s", "result");
6174 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6176 type = build_pointer_type (type);
6177 result = build_decl (PARM_DECL, result, type);
6179 push_parm_decl (result);
6182 result = NULL_TREE; /* Not ref'd if !charfunc. */
6184 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
6186 store_parm_decls (0);
6188 ffecom_start_compstmt ();
6194 ffetargetCharacterSize sz = ffesymbol_size (s);
6197 result_length = build_int_2 (sz, 0);
6198 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
6200 ffecom_prepare_let_char_ (sz, expr);
6202 ffecom_prepare_end ();
6204 ffecom_let_char_ (result, result_length, sz, expr);
6205 expand_null_return ();
6209 ffecom_prepare_expr (expr);
6211 ffecom_prepare_end ();
6213 expand_return (ffecom_modify (NULL_TREE,
6214 DECL_RESULT (current_function_decl),
6215 ffecom_expr (expr)));
6219 ffecom_end_compstmt ();
6221 func = current_function_decl;
6222 finish_function (1);
6224 pop_f_function_context ();
6228 lineno = old_lineno;
6229 input_filename = old_input_filename;
6231 ffecom_nested_entry_ = NULL;
6237 ffecom_gfrt_args_ (ffecomGfrt ix)
6239 return ffecom_gfrt_argstring_[ix];
6243 ffecom_gfrt_tree_ (ffecomGfrt ix)
6245 if (ffecom_gfrt_[ix] == NULL_TREE)
6246 ffecom_make_gfrt_ (ix);
6248 return ffecom_1 (ADDR_EXPR,
6249 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6253 /* Return initialize-to-zero expression for this VAR_DECL. */
6255 /* A somewhat evil way to prevent the garbage collector
6256 from collecting 'tree' structures. */
6257 #define NUM_TRACKED_CHUNK 63
6258 static struct tree_ggc_tracker
6260 struct tree_ggc_tracker *next;
6261 tree trees[NUM_TRACKED_CHUNK];
6262 } *tracker_head = NULL;
6265 mark_tracker_head (void *arg)
6267 struct tree_ggc_tracker *head;
6270 for (head = * (struct tree_ggc_tracker **) arg;
6275 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6276 ggc_mark_tree (head->trees[i]);
6281 ffecom_save_tree_forever (tree t)
6284 if (tracker_head != NULL)
6285 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6286 if (tracker_head->trees[i] == NULL)
6288 tracker_head->trees[i] = t;
6293 /* Need to allocate a new block. */
6294 struct tree_ggc_tracker *old_head = tracker_head;
6296 tracker_head = ggc_alloc (sizeof (*tracker_head));
6297 tracker_head->next = old_head;
6298 tracker_head->trees[0] = t;
6299 for (i = 1; i < NUM_TRACKED_CHUNK; i++)
6300 tracker_head->trees[i] = NULL;
6305 ffecom_init_zero_ (tree decl)
6308 int incremental = TREE_STATIC (decl);
6309 tree type = TREE_TYPE (decl);
6313 make_decl_rtl (decl, NULL);
6314 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
6317 if ((TREE_CODE (type) != ARRAY_TYPE)
6318 && (TREE_CODE (type) != RECORD_TYPE)
6319 && (TREE_CODE (type) != UNION_TYPE)
6321 init = convert (type, integer_zero_node);
6322 else if (!incremental)
6324 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
6325 TREE_CONSTANT (init) = 1;
6326 TREE_STATIC (init) = 1;
6330 assemble_zeros (int_size_in_bytes (type));
6331 init = error_mark_node;
6338 ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
6344 switch (ffebld_op (arg))
6346 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6347 if (ffetarget_length_character1
6348 (ffebld_constant_character1
6349 (ffebld_conter (arg))) == 0)
6351 *maybe_tree = integer_zero_node;
6352 return convert (tree_type, integer_zero_node);
6355 *maybe_tree = integer_one_node;
6356 expr_tree = build_int_2 (*ffetarget_text_character1
6357 (ffebld_constant_character1
6358 (ffebld_conter (arg))),
6360 TREE_TYPE (expr_tree) = tree_type;
6363 case FFEBLD_opSYMTER:
6364 case FFEBLD_opARRAYREF:
6365 case FFEBLD_opFUNCREF:
6366 case FFEBLD_opSUBSTR:
6367 ffecom_char_args_ (&expr_tree, &length_tree, arg);
6369 if ((expr_tree == error_mark_node)
6370 || (length_tree == error_mark_node))
6372 *maybe_tree = error_mark_node;
6373 return error_mark_node;
6376 if (integer_zerop (length_tree))
6378 *maybe_tree = integer_zero_node;
6379 return convert (tree_type, integer_zero_node);
6383 = ffecom_1 (INDIRECT_REF,
6384 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6387 = ffecom_2 (ARRAY_REF,
6388 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6391 expr_tree = convert (tree_type, expr_tree);
6393 if (TREE_CODE (length_tree) == INTEGER_CST)
6394 *maybe_tree = integer_one_node;
6395 else /* Must check length at run time. */
6397 = ffecom_truth_value
6398 (ffecom_2 (GT_EXPR, integer_type_node,
6400 ffecom_f2c_ftnlen_zero_node));
6403 case FFEBLD_opPAREN:
6404 case FFEBLD_opCONVERT:
6405 if (ffeinfo_size (ffebld_info (arg)) == 0)
6407 *maybe_tree = integer_zero_node;
6408 return convert (tree_type, integer_zero_node);
6410 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6413 case FFEBLD_opCONCATENATE:
6420 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6422 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6424 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6427 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6435 assert ("bad op in ICHAR" == NULL);
6436 return error_mark_node;
6440 /* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6444 length_arg = ffecom_intrinsic_len_ (expr);
6446 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6447 subexpressions by constructing the appropriate tree for the
6448 length-of-character-text argument in a calling sequence. */
6451 ffecom_intrinsic_len_ (ffebld expr)
6453 ffetargetCharacter1 val;
6456 switch (ffebld_op (expr))
6458 case FFEBLD_opCONTER:
6459 val = ffebld_constant_character1 (ffebld_conter (expr));
6460 length = build_int_2 (ffetarget_length_character1 (val), 0);
6461 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6464 case FFEBLD_opSYMTER:
6466 ffesymbol s = ffebld_symter (expr);
6469 item = ffesymbol_hook (s).decl_tree;
6470 if (item == NULL_TREE)
6472 s = ffecom_sym_transform_ (s);
6473 item = ffesymbol_hook (s).decl_tree;
6475 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6477 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6478 length = ffesymbol_hook (s).length_tree;
6481 length = build_int_2 (ffesymbol_size (s), 0);
6482 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6485 else if (item == error_mark_node)
6486 length = error_mark_node;
6487 else /* FFEINFO_kindFUNCTION: */
6492 case FFEBLD_opARRAYREF:
6493 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6496 case FFEBLD_opSUBSTR:
6500 ffebld thing = ffebld_right (expr);
6504 assert (ffebld_op (thing) == FFEBLD_opITEM);
6505 start = ffebld_head (thing);
6506 thing = ffebld_trail (thing);
6507 assert (ffebld_trail (thing) == NULL);
6508 end = ffebld_head (thing);
6510 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6512 if (length == error_mark_node)
6521 length = convert (ffecom_f2c_ftnlen_type_node,
6527 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6528 ffecom_expr (start));
6530 if (start_tree == error_mark_node)
6532 length = error_mark_node;
6538 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6539 ffecom_f2c_ftnlen_one_node,
6540 ffecom_2 (MINUS_EXPR,
6541 ffecom_f2c_ftnlen_type_node,
6547 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6550 if (end_tree == error_mark_node)
6552 length = error_mark_node;
6556 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6557 ffecom_f2c_ftnlen_one_node,
6558 ffecom_2 (MINUS_EXPR,
6559 ffecom_f2c_ftnlen_type_node,
6560 end_tree, start_tree));
6566 case FFEBLD_opCONCATENATE:
6568 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6569 ffecom_intrinsic_len_ (ffebld_left (expr)),
6570 ffecom_intrinsic_len_ (ffebld_right (expr)));
6573 case FFEBLD_opFUNCREF:
6574 case FFEBLD_opCONVERT:
6575 length = build_int_2 (ffebld_size (expr), 0);
6576 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6580 assert ("bad op for single char arg expr" == NULL);
6581 length = ffecom_f2c_ftnlen_zero_node;
6585 assert (length != NULL_TREE);
6590 /* Handle CHARACTER assignments.
6592 Generates code to do the assignment. Used by ordinary assignment
6593 statement handler ffecom_let_stmt and by statement-function
6594 handler to generate code for a statement function. */
6597 ffecom_let_char_ (tree dest_tree, tree dest_length,
6598 ffetargetCharacterSize dest_size, ffebld source)
6600 ffecomConcatList_ catlist;
6605 if ((dest_tree == error_mark_node)
6606 || (dest_length == error_mark_node))
6609 assert (dest_tree != NULL_TREE);
6610 assert (dest_length != NULL_TREE);
6612 /* Source might be an opCONVERT, which just means it is a different size
6613 than the destination. Since the underlying implementation here handles
6614 that (directly or via the s_copy or s_cat run-time-library functions),
6615 we don't need the "convenience" of an opCONVERT that tells us to
6616 truncate or blank-pad, particularly since the resulting implementation
6617 would probably be slower than otherwise. */
6619 while (ffebld_op (source) == FFEBLD_opCONVERT)
6620 source = ffebld_left (source);
6622 catlist = ffecom_concat_list_new_ (source, dest_size);
6623 switch (ffecom_concat_list_count_ (catlist))
6625 case 0: /* Shouldn't happen, but in case it does... */
6626 ffecom_concat_list_kill_ (catlist);
6627 source_tree = null_pointer_node;
6628 source_length = ffecom_f2c_ftnlen_zero_node;
6629 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6630 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6631 TREE_CHAIN (TREE_CHAIN (expr_tree))
6632 = build_tree_list (NULL_TREE, dest_length);
6633 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6634 = build_tree_list (NULL_TREE, source_length);
6636 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6637 TREE_SIDE_EFFECTS (expr_tree) = 1;
6639 expand_expr_stmt (expr_tree);
6643 case 1: /* The (fairly) easy case. */
6644 ffecom_char_args_ (&source_tree, &source_length,
6645 ffecom_concat_list_expr_ (catlist, 0));
6646 ffecom_concat_list_kill_ (catlist);
6647 assert (source_tree != NULL_TREE);
6648 assert (source_length != NULL_TREE);
6650 if ((source_tree == error_mark_node)
6651 || (source_length == error_mark_node))
6657 = ffecom_1 (INDIRECT_REF,
6658 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6662 = ffecom_2 (ARRAY_REF,
6663 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6668 = ffecom_1 (INDIRECT_REF,
6669 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6673 = ffecom_2 (ARRAY_REF,
6674 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6679 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
6681 expand_expr_stmt (expr_tree);
6686 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6687 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6688 TREE_CHAIN (TREE_CHAIN (expr_tree))
6689 = build_tree_list (NULL_TREE, dest_length);
6690 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6691 = build_tree_list (NULL_TREE, source_length);
6693 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6694 TREE_SIDE_EFFECTS (expr_tree) = 1;
6696 expand_expr_stmt (expr_tree);
6700 default: /* Must actually concatenate things. */
6704 /* Heavy-duty concatenation. */
6707 int count = ffecom_concat_list_count_ (catlist);
6719 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
6720 FFETARGET_charactersizeNONE, count, TRUE);
6721 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
6722 FFETARGET_charactersizeNONE,
6728 hook = ffebld_nonter_hook (source);
6730 assert (TREE_CODE (hook) == TREE_VEC);
6731 assert (TREE_VEC_LENGTH (hook) == 2);
6732 length_array = lengths = TREE_VEC_ELT (hook, 0);
6733 item_array = items = TREE_VEC_ELT (hook, 1);
6737 for (i = 0; i < count; ++i)
6739 ffecom_char_args_ (&citem, &clength,
6740 ffecom_concat_list_expr_ (catlist, i));
6741 if ((citem == error_mark_node)
6742 || (clength == error_mark_node))
6744 ffecom_concat_list_kill_ (catlist);
6749 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6750 ffecom_modify (void_type_node,
6751 ffecom_2 (ARRAY_REF,
6752 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6754 build_int_2 (i, 0)),
6758 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6759 ffecom_modify (void_type_node,
6760 ffecom_2 (ARRAY_REF,
6761 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6763 build_int_2 (i, 0)),
6768 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6769 TREE_CHAIN (expr_tree)
6770 = build_tree_list (NULL_TREE,
6771 ffecom_1 (ADDR_EXPR,
6772 build_pointer_type (TREE_TYPE (items)),
6774 TREE_CHAIN (TREE_CHAIN (expr_tree))
6775 = build_tree_list (NULL_TREE,
6776 ffecom_1 (ADDR_EXPR,
6777 build_pointer_type (TREE_TYPE (lengths)),
6779 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6782 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6783 convert (ffecom_f2c_ftnlen_type_node,
6784 build_int_2 (count, 0))));
6785 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6786 = build_tree_list (NULL_TREE, dest_length);
6788 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6789 TREE_SIDE_EFFECTS (expr_tree) = 1;
6791 expand_expr_stmt (expr_tree);
6794 ffecom_concat_list_kill_ (catlist);
6797 /* ffecom_make_gfrt_ -- Make initial info for run-time routine
6800 ffecom_make_gfrt_(ix);
6802 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6803 for the indicated run-time routine (ix). */
6806 ffecom_make_gfrt_ (ffecomGfrt ix)
6811 switch (ffecom_gfrt_type_[ix])
6813 case FFECOM_rttypeVOID_:
6814 ttype = void_type_node;
6817 case FFECOM_rttypeVOIDSTAR_:
6818 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
6821 case FFECOM_rttypeFTNINT_:
6822 ttype = ffecom_f2c_ftnint_type_node;
6825 case FFECOM_rttypeINTEGER_:
6826 ttype = ffecom_f2c_integer_type_node;
6829 case FFECOM_rttypeLONGINT_:
6830 ttype = ffecom_f2c_longint_type_node;
6833 case FFECOM_rttypeLOGICAL_:
6834 ttype = ffecom_f2c_logical_type_node;
6837 case FFECOM_rttypeREAL_F2C_:
6838 ttype = double_type_node;
6841 case FFECOM_rttypeREAL_GNU_:
6842 ttype = float_type_node;
6845 case FFECOM_rttypeCOMPLEX_F2C_:
6846 ttype = void_type_node;
6849 case FFECOM_rttypeCOMPLEX_GNU_:
6850 ttype = ffecom_f2c_complex_type_node;
6853 case FFECOM_rttypeDOUBLE_:
6854 ttype = double_type_node;
6857 case FFECOM_rttypeDOUBLEREAL_:
6858 ttype = ffecom_f2c_doublereal_type_node;
6861 case FFECOM_rttypeDBLCMPLX_F2C_:
6862 ttype = void_type_node;
6865 case FFECOM_rttypeDBLCMPLX_GNU_:
6866 ttype = ffecom_f2c_doublecomplex_type_node;
6869 case FFECOM_rttypeCHARACTER_:
6870 ttype = void_type_node;
6875 assert ("bad rttype" == NULL);
6879 ttype = build_function_type (ttype, NULL_TREE);
6880 t = build_decl (FUNCTION_DECL,
6881 get_identifier (ffecom_gfrt_name_[ix]),
6883 DECL_EXTERNAL (t) = 1;
6884 TREE_READONLY (t) = ffecom_gfrt_const_[ix] ? 1 : 0;
6885 TREE_PUBLIC (t) = 1;
6886 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
6888 /* Sanity check: A function that's const cannot be volatile. */
6890 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_volatile_[ix] : 1);
6892 /* Sanity check: A function that's const cannot return complex. */
6894 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_complex_[ix] : 1);
6896 t = start_decl (t, TRUE);
6898 finish_decl (t, NULL_TREE, TRUE);
6900 ffecom_gfrt_[ix] = t;
6903 /* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
6906 ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
6908 ffesymbol s = ffestorag_symbol (st);
6910 if (ffesymbol_namelisted (s))
6911 ffecom_member_namelisted_ = TRUE;
6914 /* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
6915 the member so debugger will see it. Otherwise nobody should be
6916 referencing the member. */
6919 ffecom_member_phase2_ (ffestorag mst, ffestorag st)
6927 || ((mt = ffestorag_hook (mst)) == NULL)
6928 || (mt == error_mark_node))
6932 || ((s = ffestorag_symbol (st)) == NULL))
6935 type = ffecom_type_localvar_ (s,
6936 ffesymbol_basictype (s),
6937 ffesymbol_kindtype (s));
6938 if (type == error_mark_node)
6941 t = build_decl (VAR_DECL,
6942 ffecom_get_identifier_ (ffesymbol_text (s)),
6945 TREE_STATIC (t) = TREE_STATIC (mt);
6946 DECL_INITIAL (t) = NULL_TREE;
6947 TREE_ASM_WRITTEN (t) = 1;
6951 gen_rtx (MEM, TYPE_MODE (type),
6952 plus_constant (XEXP (DECL_RTL (mt), 0),
6953 ffestorag_modulo (mst)
6954 + ffestorag_offset (st)
6955 - ffestorag_offset (mst))));
6957 t = start_decl (t, FALSE);
6959 finish_decl (t, NULL_TREE, FALSE);
6962 /* Prepare source expression for assignment into a destination perhaps known
6963 to be of a specific size. */
6966 ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
6968 ffecomConcatList_ catlist;
6973 tree tempvar = NULL_TREE;
6975 while (ffebld_op (source) == FFEBLD_opCONVERT)
6976 source = ffebld_left (source);
6978 catlist = ffecom_concat_list_new_ (source, dest_size);
6979 count = ffecom_concat_list_count_ (catlist);
6984 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
6985 FFETARGET_charactersizeNONE, count);
6987 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
6988 FFETARGET_charactersizeNONE, count);
6990 tempvar = make_tree_vec (2);
6991 TREE_VEC_ELT (tempvar, 0) = ltmp;
6992 TREE_VEC_ELT (tempvar, 1) = itmp;
6995 for (i = 0; i < count; ++i)
6996 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
6998 ffecom_concat_list_kill_ (catlist);
7002 ffebld_nonter_set_hook (source, tempvar);
7003 current_binding_level->prep_state = 1;
7007 /* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
7009 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
7010 (which generates their trees) and then their trees get push_parm_decl'd.
7012 The second arg is TRUE if the dummies are for a statement function, in
7013 which case lengths are not pushed for character arguments (since they are
7014 always known by both the caller and the callee, though the code allows
7015 for someday permitting CHAR*(*) stmtfunc dummies). */
7018 ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
7025 ffecom_transform_only_dummies_ = TRUE;
7027 /* First push the parms corresponding to actual dummy "contents". */
7029 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7031 dummy = ffebld_head (dumlist);
7032 switch (ffebld_op (dummy))
7036 continue; /* Forget alternate returns. */
7041 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7042 s = ffebld_symter (dummy);
7043 parm = ffesymbol_hook (s).decl_tree;
7044 if (parm == NULL_TREE)
7046 s = ffecom_sym_transform_ (s);
7047 parm = ffesymbol_hook (s).decl_tree;
7048 assert (parm != NULL_TREE);
7050 if (parm != error_mark_node)
7051 push_parm_decl (parm);
7054 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
7056 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7058 dummy = ffebld_head (dumlist);
7059 switch (ffebld_op (dummy))
7063 continue; /* Forget alternate returns, they mean
7069 s = ffebld_symter (dummy);
7070 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7071 continue; /* Only looking for CHARACTER arguments. */
7072 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7073 continue; /* Stmtfunc arg with known size needs no
7075 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7076 continue; /* Only looking for variables and arrays. */
7077 parm = ffesymbol_hook (s).length_tree;
7078 assert (parm != NULL_TREE);
7079 if (parm != error_mark_node)
7080 push_parm_decl (parm);
7083 ffecom_transform_only_dummies_ = FALSE;
7086 /* ffecom_start_progunit_ -- Beginning of program unit
7088 Does GNU back end stuff necessary to teach it about the start of its
7089 equivalent of a Fortran program unit. */
7092 ffecom_start_progunit_ ()
7094 ffesymbol fn = ffecom_primary_entry_;
7096 tree id; /* Identifier (name) of function. */
7097 tree type; /* Type of function. */
7098 tree result; /* Result of function. */
7099 ffeinfoBasictype bt;
7103 ffeglobalType egt = FFEGLOBAL_type;
7106 bool altentries = (ffecom_num_entrypoints_ != 0);
7109 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7110 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7111 bool main_program = FALSE;
7112 int old_lineno = lineno;
7113 const char *old_input_filename = input_filename;
7115 assert (fn != NULL);
7116 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
7118 input_filename = ffesymbol_where_filename (fn);
7119 lineno = ffesymbol_where_filelinenum (fn);
7121 switch (ffecom_primary_entry_kind_)
7123 case FFEINFO_kindPROGRAM:
7124 main_program = TRUE;
7125 gt = FFEGLOBAL_typeMAIN;
7126 bt = FFEINFO_basictypeNONE;
7127 kt = FFEINFO_kindtypeNONE;
7128 type = ffecom_tree_fun_type_void;
7133 case FFEINFO_kindBLOCKDATA:
7134 gt = FFEGLOBAL_typeBDATA;
7135 bt = FFEINFO_basictypeNONE;
7136 kt = FFEINFO_kindtypeNONE;
7137 type = ffecom_tree_fun_type_void;
7142 case FFEINFO_kindFUNCTION:
7143 gt = FFEGLOBAL_typeFUNC;
7144 egt = FFEGLOBAL_typeEXT;
7145 bt = ffesymbol_basictype (fn);
7146 kt = ffesymbol_kindtype (fn);
7147 if (bt == FFEINFO_basictypeNONE)
7149 ffeimplic_establish_symbol (fn);
7150 if (ffesymbol_funcresult (fn) != NULL)
7151 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7152 bt = ffesymbol_basictype (fn);
7153 kt = ffesymbol_kindtype (fn);
7157 charfunc = cmplxfunc = FALSE;
7158 else if (bt == FFEINFO_basictypeCHARACTER)
7159 charfunc = TRUE, cmplxfunc = FALSE;
7160 else if ((bt == FFEINFO_basictypeCOMPLEX)
7161 && ffesymbol_is_f2c (fn)
7163 charfunc = FALSE, cmplxfunc = TRUE;
7165 charfunc = cmplxfunc = FALSE;
7167 if (multi || charfunc)
7168 type = ffecom_tree_fun_type_void;
7169 else if (ffesymbol_is_f2c (fn) && !altentries)
7170 type = ffecom_tree_fun_type[bt][kt];
7172 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7174 if ((type == NULL_TREE)
7175 || (TREE_TYPE (type) == NULL_TREE))
7176 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7179 case FFEINFO_kindSUBROUTINE:
7180 gt = FFEGLOBAL_typeSUBR;
7181 egt = FFEGLOBAL_typeEXT;
7182 bt = FFEINFO_basictypeNONE;
7183 kt = FFEINFO_kindtypeNONE;
7184 if (ffecom_is_altreturning_)
7185 type = ffecom_tree_subr_type;
7187 type = ffecom_tree_fun_type_void;
7193 assert ("say what??" == NULL);
7195 case FFEINFO_kindANY:
7196 gt = FFEGLOBAL_typeANY;
7197 bt = FFEINFO_basictypeNONE;
7198 kt = FFEINFO_kindtypeNONE;
7199 type = error_mark_node;
7207 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
7208 ffesymbol_text (fn));
7210 #if FFETARGET_isENFORCED_MAIN
7211 else if (main_program)
7212 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7215 id = ffecom_get_external_identifier_ (fn);
7219 0, /* nested/inline */
7220 !altentries); /* TREE_PUBLIC */
7222 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
7225 && ((g = ffesymbol_global (fn)) != NULL)
7226 && ((ffeglobal_type (g) == gt)
7227 || (ffeglobal_type (g) == egt)))
7229 ffeglobal_set_hook (g, current_function_decl);
7232 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7233 exec-transitioning needs current_function_decl to be filled in. So we
7234 do these things in two phases. */
7237 { /* 1st arg identifies which entrypoint. */
7238 ffecom_which_entrypoint_decl_
7239 = build_decl (PARM_DECL,
7240 ffecom_get_invented_identifier ("__g77_%s",
7241 "which_entrypoint"),
7243 push_parm_decl (ffecom_which_entrypoint_decl_);
7249 { /* Arg for result (return value). */
7254 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7256 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7258 type = ffecom_multi_type_node_;
7260 result = ffecom_get_invented_identifier ("__g77_%s", "result");
7262 /* Make length arg _and_ enhance type info for CHAR arg itself. */
7265 length = ffecom_char_enhance_arg_ (&type, fn);
7267 length = NULL_TREE; /* Not ref'd if !charfunc. */
7269 type = build_pointer_type (type);
7270 result = build_decl (PARM_DECL, result, type);
7272 push_parm_decl (result);
7274 ffecom_multi_retval_ = result;
7276 ffecom_func_result_ = result;
7280 push_parm_decl (length);
7281 ffecom_func_length_ = length;
7285 if (ffecom_primary_entry_is_proc_)
7288 arglist = ffecom_master_arglist_;
7290 arglist = ffesymbol_dummyargs (fn);
7291 ffecom_push_dummy_decls_ (arglist, FALSE);
7294 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7295 store_parm_decls (main_program ? 1 : 0);
7297 ffecom_start_compstmt ();
7298 /* Disallow temp vars at this level. */
7299 current_binding_level->prep_state = 2;
7301 lineno = old_lineno;
7302 input_filename = old_input_filename;
7304 /* This handles any symbols still untransformed, in case -g specified.
7305 This used to be done in ffecom_finish_progunit, but it turns out to
7306 be necessary to do it here so that statement functions are
7307 expanded before code. But don't bother for BLOCK DATA. */
7309 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7310 ffesymbol_drive (ffecom_finish_symbol_transform_);
7313 /* ffecom_sym_transform_ -- Transform FFE sym into backend sym
7316 ffecom_sym_transform_(s);
7318 The ffesymbol_hook info for s is updated with appropriate backend info
7322 ffecom_sym_transform_ (ffesymbol s)
7324 tree t; /* Transformed thingy. */
7325 tree tlen; /* Length if CHAR*(*). */
7326 bool addr; /* Is t the address of the thingy? */
7327 ffeinfoBasictype bt;
7330 int old_lineno = lineno;
7331 const char *old_input_filename = input_filename;
7333 /* Must ensure special ASSIGN variables are declared at top of outermost
7334 block, else they'll end up in the innermost block when their first
7335 ASSIGN is seen, which leaves them out of scope when they're the
7336 subject of a GOTO or I/O statement.
7338 We make this variable even if -fugly-assign. Just let it go unused,
7339 in case it turns out there are cases where we really want to use this
7340 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
7342 if (! ffecom_transform_only_dummies_
7343 && ffesymbol_assigned (s)
7344 && ! ffesymbol_hook (s).assign_tree)
7345 s = ffecom_sym_transform_assign_ (s);
7347 if (ffesymbol_sfdummyparent (s) == NULL)
7349 input_filename = ffesymbol_where_filename (s);
7350 lineno = ffesymbol_where_filelinenum (s);
7354 ffesymbol sf = ffesymbol_sfdummyparent (s);
7356 input_filename = ffesymbol_where_filename (sf);
7357 lineno = ffesymbol_where_filelinenum (sf);
7360 bt = ffeinfo_basictype (ffebld_info (s));
7361 kt = ffeinfo_kindtype (ffebld_info (s));
7367 switch (ffesymbol_kind (s))
7369 case FFEINFO_kindNONE:
7370 switch (ffesymbol_where (s))
7372 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7373 assert (ffecom_transform_only_dummies_);
7375 /* Before 0.4, this could be ENTITY/DUMMY, but see
7376 ffestu_sym_end_transition -- no longer true (in particular, if
7377 it could be an ENTITY, it _will_ be made one, so that
7378 possibility won't come through here). So we never make length
7379 arg for CHARACTER type. */
7381 t = build_decl (PARM_DECL,
7382 ffecom_get_identifier_ (ffesymbol_text (s)),
7383 ffecom_tree_ptr_to_subr_type);
7384 DECL_ARTIFICIAL (t) = 1;
7388 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7389 assert (!ffecom_transform_only_dummies_);
7391 if (((g = ffesymbol_global (s)) != NULL)
7392 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7393 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7394 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7395 && (ffeglobal_hook (g) != NULL_TREE)
7396 && ffe_is_globals ())
7398 t = ffeglobal_hook (g);
7402 t = build_decl (FUNCTION_DECL,
7403 ffecom_get_external_identifier_ (s),
7404 ffecom_tree_subr_type); /* Assume subr. */
7405 DECL_EXTERNAL (t) = 1;
7406 TREE_PUBLIC (t) = 1;
7408 t = start_decl (t, FALSE);
7409 finish_decl (t, NULL_TREE, FALSE);
7412 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7413 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7414 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7415 ffeglobal_set_hook (g, t);
7417 ffecom_save_tree_forever (t);
7422 assert ("NONE where unexpected" == NULL);
7424 case FFEINFO_whereANY:
7429 case FFEINFO_kindENTITY:
7430 switch (ffeinfo_where (ffesymbol_info (s)))
7433 case FFEINFO_whereCONSTANT:
7434 /* ~~Debugging info needed? */
7435 assert (!ffecom_transform_only_dummies_);
7436 t = error_mark_node; /* Shouldn't ever see this in expr. */
7439 case FFEINFO_whereLOCAL:
7440 assert (!ffecom_transform_only_dummies_);
7443 ffestorag st = ffesymbol_storage (s);
7447 && (ffestorag_size (st) == 0))
7449 t = error_mark_node;
7453 type = ffecom_type_localvar_ (s, bt, kt);
7455 if (type == error_mark_node)
7457 t = error_mark_node;
7462 && (ffestorag_parent (st) != NULL))
7463 { /* Child of EQUIVALENCE parent. */
7466 ffetargetOffset offset;
7468 est = ffestorag_parent (st);
7469 ffecom_transform_equiv_ (est);
7471 et = ffestorag_hook (est);
7472 assert (et != NULL_TREE);
7474 if (! TREE_STATIC (et))
7475 put_var_into_stack (et);
7477 offset = ffestorag_modulo (est)
7478 + ffestorag_offset (ffesymbol_storage (s))
7479 - ffestorag_offset (est);
7481 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
7483 /* (t_type *) (((char *) &et) + offset) */
7485 t = convert (string_type_node, /* (char *) */
7486 ffecom_1 (ADDR_EXPR,
7487 build_pointer_type (TREE_TYPE (et)),
7489 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7491 build_int_2 (offset, 0));
7492 t = convert (build_pointer_type (type),
7494 TREE_CONSTANT (t) = staticp (et);
7501 bool init = ffesymbol_is_init (s);
7503 t = build_decl (VAR_DECL,
7504 ffecom_get_identifier_ (ffesymbol_text (s)),
7508 || ffesymbol_namelisted (s)
7509 #ifdef FFECOM_sizeMAXSTACKITEM
7511 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7513 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7514 && (ffecom_primary_entry_kind_
7515 != FFEINFO_kindBLOCKDATA)
7516 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7517 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7519 TREE_STATIC (t) = 0; /* No need to make static. */
7521 if (init || ffe_is_init_local_zero ())
7522 DECL_INITIAL (t) = error_mark_node;
7524 /* Keep -Wunused from complaining about var if it
7525 is used as sfunc arg or DATA implied-DO. */
7526 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7527 DECL_IN_SYSTEM_HEADER (t) = 1;
7529 t = start_decl (t, FALSE);
7533 if (ffesymbol_init (s) != NULL)
7534 initexpr = ffecom_expr (ffesymbol_init (s));
7536 initexpr = ffecom_init_zero_ (t);
7538 else if (ffe_is_init_local_zero ())
7539 initexpr = ffecom_init_zero_ (t);
7541 initexpr = NULL_TREE; /* Not ref'd if !init. */
7543 finish_decl (t, initexpr, FALSE);
7545 if (st != NULL && DECL_SIZE (t) != error_mark_node)
7547 assert (TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST);
7548 assert (0 == compare_tree_int (DECL_SIZE_UNIT (t),
7549 ffestorag_size (st)));
7555 case FFEINFO_whereRESULT:
7556 assert (!ffecom_transform_only_dummies_);
7558 if (bt == FFEINFO_basictypeCHARACTER)
7559 { /* Result is already in list of dummies, use
7561 t = ffecom_func_result_;
7562 tlen = ffecom_func_length_;
7566 if ((ffecom_num_entrypoints_ == 0)
7567 && (bt == FFEINFO_basictypeCOMPLEX)
7568 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7569 { /* Result is already in list of dummies, use
7571 t = ffecom_func_result_;
7575 if (ffecom_func_result_ != NULL_TREE)
7577 t = ffecom_func_result_;
7580 if ((ffecom_num_entrypoints_ != 0)
7581 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7583 assert (ffecom_multi_retval_ != NULL_TREE);
7584 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7585 ffecom_multi_retval_);
7586 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7587 t, ffecom_multi_fields_[bt][kt]);
7592 t = build_decl (VAR_DECL,
7593 ffecom_get_identifier_ (ffesymbol_text (s)),
7594 ffecom_tree_type[bt][kt]);
7595 TREE_STATIC (t) = 0; /* Put result on stack. */
7596 t = start_decl (t, FALSE);
7597 finish_decl (t, NULL_TREE, FALSE);
7599 ffecom_func_result_ = t;
7603 case FFEINFO_whereDUMMY:
7611 bool adjustable = FALSE; /* Conditionally adjustable? */
7613 type = ffecom_tree_type[bt][kt];
7614 if (ffesymbol_sfdummyparent (s) != NULL)
7616 if (current_function_decl == ffecom_outer_function_decl_)
7617 { /* Exec transition before sfunc
7618 context; get it later. */
7621 t = ffecom_get_identifier_ (ffesymbol_text
7622 (ffesymbol_sfdummyparent (s)));
7625 t = ffecom_get_identifier_ (ffesymbol_text (s));
7627 assert (ffecom_transform_only_dummies_);
7629 old_sizes = get_pending_sizes ();
7630 put_pending_sizes (old_sizes);
7632 if (bt == FFEINFO_basictypeCHARACTER)
7633 tlen = ffecom_char_enhance_arg_ (&type, s);
7634 type = ffecom_check_size_overflow_ (s, type, TRUE);
7636 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7638 if (type == error_mark_node)
7641 dim = ffebld_head (dl);
7642 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7643 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7644 low = ffecom_integer_one_node;
7646 low = ffecom_expr (ffebld_left (dim));
7647 assert (ffebld_right (dim) != NULL);
7648 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7649 || ffecom_doing_entry_)
7651 /* Used to just do high=low. But for ffecom_tree_
7652 canonize_ref_, it probably is important to correctly
7653 assess the size. E.g. given COMPLEX C(*),CFUNC and
7654 C(2)=CFUNC(C), overlap can happen, while it can't
7655 for, say, C(1)=CFUNC(C(2)). */
7656 /* Even more recently used to set to INT_MAX, but that
7657 broke when some overflow checking went into the back
7658 end. Now we just leave the upper bound unspecified. */
7662 high = ffecom_expr (ffebld_right (dim));
7664 /* Determine whether array is conditionally adjustable,
7665 to decide whether back-end magic is needed.
7667 Normally the front end uses the back-end function
7668 variable_size to wrap SAVE_EXPR's around expressions
7669 affecting the size/shape of an array so that the
7670 size/shape info doesn't change during execution
7671 of the compiled code even though variables and
7672 functions referenced in those expressions might.
7674 variable_size also makes sure those saved expressions
7675 get evaluated immediately upon entry to the
7676 compiled procedure -- the front end normally doesn't
7677 have to worry about that.
7679 However, there is a problem with this that affects
7680 g77's implementation of entry points, and that is
7681 that it is _not_ true that each invocation of the
7682 compiled procedure is permitted to evaluate
7683 array size/shape info -- because it is possible
7684 that, for some invocations, that info is invalid (in
7685 which case it is "promised" -- i.e. a violation of
7686 the Fortran standard -- that the compiled code
7687 won't reference the array or its size/shape
7688 during that particular invocation).
7690 To phrase this in C terms, consider this gcc function:
7692 void foo (int *n, float (*a)[*n])
7694 // a is "pointer to array ...", fyi.
7697 Suppose that, for some invocations, it is permitted
7698 for a caller of foo to do this:
7702 Now the _written_ code for foo can take such a call
7703 into account by either testing explicitly for whether
7704 (a == NULL) || (n == NULL) -- presumably it is
7705 not permitted to reference *a in various fashions
7706 if (n == NULL) I suppose -- or it can avoid it by
7707 looking at other info (other arguments, static/global
7710 However, this won't work in gcc 2.5.8 because it'll
7711 automatically emit the code to save the "*n"
7712 expression, which'll yield a NULL dereference for
7713 the "foo (NULL, NULL)" call, something the code
7714 for foo cannot prevent.
7716 g77 definitely needs to avoid executing such
7717 code anytime the pointer to the adjustable array
7718 is NULL, because even if its bounds expressions
7719 don't have any references to possible "absent"
7720 variables like "*n" -- say all variable references
7721 are to COMMON variables, i.e. global (though in C,
7722 local static could actually make sense) -- the
7723 expressions could yield other run-time problems
7724 for allowably "dead" values in those variables.
7726 For example, let's consider a more complicated
7732 void foo (float (*a)[i/j])
7737 The above is (essentially) quite valid for Fortran
7738 but, again, for a call like "foo (NULL);", it is
7739 permitted for i and j to be undefined when the
7740 call is made. If j happened to be zero, for
7741 example, emitting the code to evaluate "i/j"
7742 could result in a run-time error.
7744 Offhand, though I don't have my F77 or F90
7745 standards handy, it might even be valid for a
7746 bounds expression to contain a function reference,
7747 in which case I doubt it is permitted for an
7748 implementation to invoke that function in the
7749 Fortran case involved here (invocation of an
7750 alternate ENTRY point that doesn't have the adjustable
7751 array as one of its arguments).
7753 So, the code that the compiler would normally emit
7754 to preevaluate the size/shape info for an
7755 adjustable array _must not_ be executed at run time
7756 in certain cases. Specifically, for Fortran,
7757 the case is when the pointer to the adjustable
7758 array == NULL. (For gnu-ish C, it might be nice
7759 for the source code itself to specify an expression
7760 that, if TRUE, inhibits execution of the code. Or
7761 reverse the sense for elegance.)
7763 (Note that g77 could use a different test than NULL,
7764 actually, since it happens to always pass an
7765 integer to the called function that specifies which
7766 entry point is being invoked. Hmm, this might
7767 solve the next problem.)
7769 One way a user could, I suppose, write "foo" so
7770 it works is to insert COND_EXPR's for the
7771 size/shape info so the dangerous stuff isn't
7772 actually done, as in:
7774 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7779 The next problem is that the front end needs to
7780 be able to tell the back end about the array's
7781 decl _before_ it tells it about the conditional
7782 expression to inhibit evaluation of size/shape info,
7785 To solve this, the front end needs to be able
7786 to give the back end the expression to inhibit
7787 generation of the preevaluation code _after_
7788 it makes the decl for the adjustable array.
7790 Until then, the above example using the COND_EXPR
7791 doesn't pass muster with gcc because the "(a == NULL)"
7792 part has a reference to "a", which is still
7793 undefined at that point.
7795 g77 will therefore use a different mechanism in the
7799 && ((TREE_CODE (low) != INTEGER_CST)
7800 || (high && TREE_CODE (high) != INTEGER_CST)))
7803 #if 0 /* Old approach -- see below. */
7804 if (TREE_CODE (low) != INTEGER_CST)
7805 low = ffecom_3 (COND_EXPR, integer_type_node,
7806 ffecom_adjarray_passed_ (s),
7808 ffecom_integer_zero_node);
7810 if (high && TREE_CODE (high) != INTEGER_CST)
7811 high = ffecom_3 (COND_EXPR, integer_type_node,
7812 ffecom_adjarray_passed_ (s),
7814 ffecom_integer_zero_node);
7817 /* ~~~gcc/stor-layout.c (layout_type) should do this,
7818 probably. Fixes 950302-1.f. */
7820 if (TREE_CODE (low) != INTEGER_CST)
7821 low = variable_size (low);
7823 /* ~~~Similarly, this fixes dumb0.f. The C front end
7824 does this, which is why dumb0.c would work. */
7826 if (high && TREE_CODE (high) != INTEGER_CST)
7827 high = variable_size (high);
7832 build_range_type (ffecom_integer_type_node,
7834 type = ffecom_check_size_overflow_ (s, type, TRUE);
7837 if (type == error_mark_node)
7839 t = error_mark_node;
7843 if ((ffesymbol_sfdummyparent (s) == NULL)
7844 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
7846 type = build_pointer_type (type);
7850 t = build_decl (PARM_DECL, t, type);
7851 DECL_ARTIFICIAL (t) = 1;
7853 /* If this arg is present in every entry point's list of
7854 dummy args, then we're done. */
7856 if (ffesymbol_numentries (s)
7857 == (ffecom_num_entrypoints_ + 1))
7862 /* If variable_size in stor-layout has been called during
7863 the above, then get_pending_sizes should have the
7864 yet-to-be-evaluated saved expressions pending.
7865 Make the whole lot of them get emitted, conditionally
7866 on whether the array decl ("t" above) is not NULL. */
7869 tree sizes = get_pending_sizes ();
7874 tem = TREE_CHAIN (tem))
7876 tree temv = TREE_VALUE (tem);
7882 = ffecom_2 (COMPOUND_EXPR,
7891 = ffecom_3 (COND_EXPR,
7898 convert (TREE_TYPE (sizes),
7899 integer_zero_node));
7900 sizes = ffecom_save_tree (sizes);
7903 = tree_cons (NULL_TREE, sizes, tem);
7907 put_pending_sizes (sizes);
7913 && (ffesymbol_numentries (s)
7914 != ffecom_num_entrypoints_ + 1))
7916 = ffecom_2 (NE_EXPR, integer_type_node,
7922 && (ffesymbol_numentries (s)
7923 != ffecom_num_entrypoints_ + 1))
7925 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
7926 ffebad_here (0, ffesymbol_where_line (s),
7927 ffesymbol_where_column (s));
7928 ffebad_string (ffesymbol_text (s));
7937 case FFEINFO_whereCOMMON:
7942 ffestorag st = ffesymbol_storage (s);
7945 cs = ffesymbol_common (s); /* The COMMON area itself. */
7946 if (st != NULL) /* Else not laid out. */
7948 ffecom_transform_common_ (cs);
7949 st = ffesymbol_storage (s);
7952 type = ffecom_type_localvar_ (s, bt, kt);
7954 cg = ffesymbol_global (cs); /* The global COMMON info. */
7956 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
7959 ct = ffeglobal_hook (cg); /* The common area's tree. */
7961 if ((ct == NULL_TREE)
7963 || (type == error_mark_node))
7964 t = error_mark_node;
7967 ffetargetOffset offset;
7970 cst = ffestorag_parent (st);
7971 assert (cst == ffesymbol_storage (cs));
7973 offset = ffestorag_modulo (cst)
7974 + ffestorag_offset (st)
7975 - ffestorag_offset (cst);
7977 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
7979 /* (t_type *) (((char *) &ct) + offset) */
7981 t = convert (string_type_node, /* (char *) */
7982 ffecom_1 (ADDR_EXPR,
7983 build_pointer_type (TREE_TYPE (ct)),
7985 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7987 build_int_2 (offset, 0));
7988 t = convert (build_pointer_type (type),
7990 TREE_CONSTANT (t) = 1;
7997 case FFEINFO_whereIMMEDIATE:
7998 case FFEINFO_whereGLOBAL:
7999 case FFEINFO_whereFLEETING:
8000 case FFEINFO_whereFLEETING_CADDR:
8001 case FFEINFO_whereFLEETING_IADDR:
8002 case FFEINFO_whereINTRINSIC:
8003 case FFEINFO_whereCONSTANT_SUBOBJECT:
8005 assert ("ENTITY where unheard of" == NULL);
8007 case FFEINFO_whereANY:
8008 t = error_mark_node;
8013 case FFEINFO_kindFUNCTION:
8014 switch (ffeinfo_where (ffesymbol_info (s)))
8016 case FFEINFO_whereLOCAL: /* Me. */
8017 assert (!ffecom_transform_only_dummies_);
8018 t = current_function_decl;
8021 case FFEINFO_whereGLOBAL:
8022 assert (!ffecom_transform_only_dummies_);
8024 if (((g = ffesymbol_global (s)) != NULL)
8025 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8026 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8027 && (ffeglobal_hook (g) != NULL_TREE)
8028 && ffe_is_globals ())
8030 t = ffeglobal_hook (g);
8034 if (ffesymbol_is_f2c (s)
8035 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8036 t = ffecom_tree_fun_type[bt][kt];
8038 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
8040 t = build_decl (FUNCTION_DECL,
8041 ffecom_get_external_identifier_ (s),
8043 DECL_EXTERNAL (t) = 1;
8044 TREE_PUBLIC (t) = 1;
8046 t = start_decl (t, FALSE);
8047 finish_decl (t, NULL_TREE, FALSE);
8050 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8051 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8052 ffeglobal_set_hook (g, t);
8054 ffecom_save_tree_forever (t);
8058 case FFEINFO_whereDUMMY:
8059 assert (ffecom_transform_only_dummies_);
8061 if (ffesymbol_is_f2c (s)
8062 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8063 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8065 t = build_pointer_type
8066 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8068 t = build_decl (PARM_DECL,
8069 ffecom_get_identifier_ (ffesymbol_text (s)),
8071 DECL_ARTIFICIAL (t) = 1;
8075 case FFEINFO_whereCONSTANT: /* Statement function. */
8076 assert (!ffecom_transform_only_dummies_);
8077 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8080 case FFEINFO_whereINTRINSIC:
8081 assert (!ffecom_transform_only_dummies_);
8082 break; /* Let actual references generate their
8086 assert ("FUNCTION where unheard of" == NULL);
8088 case FFEINFO_whereANY:
8089 t = error_mark_node;
8094 case FFEINFO_kindSUBROUTINE:
8095 switch (ffeinfo_where (ffesymbol_info (s)))
8097 case FFEINFO_whereLOCAL: /* Me. */
8098 assert (!ffecom_transform_only_dummies_);
8099 t = current_function_decl;
8102 case FFEINFO_whereGLOBAL:
8103 assert (!ffecom_transform_only_dummies_);
8105 if (((g = ffesymbol_global (s)) != NULL)
8106 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8107 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8108 && (ffeglobal_hook (g) != NULL_TREE)
8109 && ffe_is_globals ())
8111 t = ffeglobal_hook (g);
8115 t = build_decl (FUNCTION_DECL,
8116 ffecom_get_external_identifier_ (s),
8117 ffecom_tree_subr_type);
8118 DECL_EXTERNAL (t) = 1;
8119 TREE_PUBLIC (t) = 1;
8121 t = start_decl (t, FALSE);
8122 finish_decl (t, NULL_TREE, FALSE);
8125 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8126 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8127 ffeglobal_set_hook (g, t);
8129 ffecom_save_tree_forever (t);
8133 case FFEINFO_whereDUMMY:
8134 assert (ffecom_transform_only_dummies_);
8136 t = build_decl (PARM_DECL,
8137 ffecom_get_identifier_ (ffesymbol_text (s)),
8138 ffecom_tree_ptr_to_subr_type);
8139 DECL_ARTIFICIAL (t) = 1;
8143 case FFEINFO_whereINTRINSIC:
8144 assert (!ffecom_transform_only_dummies_);
8145 break; /* Let actual references generate their
8149 assert ("SUBROUTINE where unheard of" == NULL);
8151 case FFEINFO_whereANY:
8152 t = error_mark_node;
8157 case FFEINFO_kindPROGRAM:
8158 switch (ffeinfo_where (ffesymbol_info (s)))
8160 case FFEINFO_whereLOCAL: /* Me. */
8161 assert (!ffecom_transform_only_dummies_);
8162 t = current_function_decl;
8165 case FFEINFO_whereCOMMON:
8166 case FFEINFO_whereDUMMY:
8167 case FFEINFO_whereGLOBAL:
8168 case FFEINFO_whereRESULT:
8169 case FFEINFO_whereFLEETING:
8170 case FFEINFO_whereFLEETING_CADDR:
8171 case FFEINFO_whereFLEETING_IADDR:
8172 case FFEINFO_whereIMMEDIATE:
8173 case FFEINFO_whereINTRINSIC:
8174 case FFEINFO_whereCONSTANT:
8175 case FFEINFO_whereCONSTANT_SUBOBJECT:
8177 assert ("PROGRAM where unheard of" == NULL);
8179 case FFEINFO_whereANY:
8180 t = error_mark_node;
8185 case FFEINFO_kindBLOCKDATA:
8186 switch (ffeinfo_where (ffesymbol_info (s)))
8188 case FFEINFO_whereLOCAL: /* Me. */
8189 assert (!ffecom_transform_only_dummies_);
8190 t = current_function_decl;
8193 case FFEINFO_whereGLOBAL:
8194 assert (!ffecom_transform_only_dummies_);
8196 t = build_decl (FUNCTION_DECL,
8197 ffecom_get_external_identifier_ (s),
8198 ffecom_tree_blockdata_type);
8199 DECL_EXTERNAL (t) = 1;
8200 TREE_PUBLIC (t) = 1;
8202 t = start_decl (t, FALSE);
8203 finish_decl (t, NULL_TREE, FALSE);
8205 ffecom_save_tree_forever (t);
8209 case FFEINFO_whereCOMMON:
8210 case FFEINFO_whereDUMMY:
8211 case FFEINFO_whereRESULT:
8212 case FFEINFO_whereFLEETING:
8213 case FFEINFO_whereFLEETING_CADDR:
8214 case FFEINFO_whereFLEETING_IADDR:
8215 case FFEINFO_whereIMMEDIATE:
8216 case FFEINFO_whereINTRINSIC:
8217 case FFEINFO_whereCONSTANT:
8218 case FFEINFO_whereCONSTANT_SUBOBJECT:
8220 assert ("BLOCKDATA where unheard of" == NULL);
8222 case FFEINFO_whereANY:
8223 t = error_mark_node;
8228 case FFEINFO_kindCOMMON:
8229 switch (ffeinfo_where (ffesymbol_info (s)))
8231 case FFEINFO_whereLOCAL:
8232 assert (!ffecom_transform_only_dummies_);
8233 ffecom_transform_common_ (s);
8236 case FFEINFO_whereNONE:
8237 case FFEINFO_whereCOMMON:
8238 case FFEINFO_whereDUMMY:
8239 case FFEINFO_whereGLOBAL:
8240 case FFEINFO_whereRESULT:
8241 case FFEINFO_whereFLEETING:
8242 case FFEINFO_whereFLEETING_CADDR:
8243 case FFEINFO_whereFLEETING_IADDR:
8244 case FFEINFO_whereIMMEDIATE:
8245 case FFEINFO_whereINTRINSIC:
8246 case FFEINFO_whereCONSTANT:
8247 case FFEINFO_whereCONSTANT_SUBOBJECT:
8249 assert ("COMMON where unheard of" == NULL);
8251 case FFEINFO_whereANY:
8252 t = error_mark_node;
8257 case FFEINFO_kindCONSTRUCT:
8258 switch (ffeinfo_where (ffesymbol_info (s)))
8260 case FFEINFO_whereLOCAL:
8261 assert (!ffecom_transform_only_dummies_);
8264 case FFEINFO_whereNONE:
8265 case FFEINFO_whereCOMMON:
8266 case FFEINFO_whereDUMMY:
8267 case FFEINFO_whereGLOBAL:
8268 case FFEINFO_whereRESULT:
8269 case FFEINFO_whereFLEETING:
8270 case FFEINFO_whereFLEETING_CADDR:
8271 case FFEINFO_whereFLEETING_IADDR:
8272 case FFEINFO_whereIMMEDIATE:
8273 case FFEINFO_whereINTRINSIC:
8274 case FFEINFO_whereCONSTANT:
8275 case FFEINFO_whereCONSTANT_SUBOBJECT:
8277 assert ("CONSTRUCT where unheard of" == NULL);
8279 case FFEINFO_whereANY:
8280 t = error_mark_node;
8285 case FFEINFO_kindNAMELIST:
8286 switch (ffeinfo_where (ffesymbol_info (s)))
8288 case FFEINFO_whereLOCAL:
8289 assert (!ffecom_transform_only_dummies_);
8290 t = ffecom_transform_namelist_ (s);
8293 case FFEINFO_whereNONE:
8294 case FFEINFO_whereCOMMON:
8295 case FFEINFO_whereDUMMY:
8296 case FFEINFO_whereGLOBAL:
8297 case FFEINFO_whereRESULT:
8298 case FFEINFO_whereFLEETING:
8299 case FFEINFO_whereFLEETING_CADDR:
8300 case FFEINFO_whereFLEETING_IADDR:
8301 case FFEINFO_whereIMMEDIATE:
8302 case FFEINFO_whereINTRINSIC:
8303 case FFEINFO_whereCONSTANT:
8304 case FFEINFO_whereCONSTANT_SUBOBJECT:
8306 assert ("NAMELIST where unheard of" == NULL);
8308 case FFEINFO_whereANY:
8309 t = error_mark_node;
8315 assert ("kind unheard of" == NULL);
8317 case FFEINFO_kindANY:
8318 t = error_mark_node;
8322 ffesymbol_hook (s).decl_tree = t;
8323 ffesymbol_hook (s).length_tree = tlen;
8324 ffesymbol_hook (s).addr = addr;
8326 lineno = old_lineno;
8327 input_filename = old_input_filename;
8332 /* Transform into ASSIGNable symbol.
8334 Symbol has already been transformed, but for whatever reason, the
8335 resulting decl_tree has been deemed not usable for an ASSIGN target.
8336 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8337 another local symbol of type void * and stuff that in the assign_tree
8338 argument. The F77/F90 standards allow this implementation. */
8341 ffecom_sym_transform_assign_ (ffesymbol s)
8343 tree t; /* Transformed thingy. */
8344 int old_lineno = lineno;
8345 const char *old_input_filename = input_filename;
8347 if (ffesymbol_sfdummyparent (s) == NULL)
8349 input_filename = ffesymbol_where_filename (s);
8350 lineno = ffesymbol_where_filelinenum (s);
8354 ffesymbol sf = ffesymbol_sfdummyparent (s);
8356 input_filename = ffesymbol_where_filename (sf);
8357 lineno = ffesymbol_where_filelinenum (sf);
8360 assert (!ffecom_transform_only_dummies_);
8362 t = build_decl (VAR_DECL,
8363 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
8364 ffesymbol_text (s)),
8365 TREE_TYPE (null_pointer_node));
8367 switch (ffesymbol_where (s))
8369 case FFEINFO_whereLOCAL:
8370 /* Unlike for regular vars, SAVE status is easy to determine for
8371 ASSIGNed vars, since there's no initialization, there's no
8372 effective storage association (so "SAVE J" does not apply to
8373 K even given "EQUIVALENCE (J,K)"), there's no size issue
8374 to worry about, etc. */
8375 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8376 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8377 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8378 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8380 TREE_STATIC (t) = 0; /* No need to make static. */
8383 case FFEINFO_whereCOMMON:
8384 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8387 case FFEINFO_whereDUMMY:
8388 /* Note that twinning a DUMMY means the caller won't see
8389 the ASSIGNed value. But both F77 and F90 allow implementations
8390 to do this, i.e. disallow Fortran code that would try and
8391 take advantage of actually putting a label into a variable
8392 via a dummy argument (or any other storage association, for
8394 TREE_STATIC (t) = 0;
8398 TREE_STATIC (t) = 0;
8402 t = start_decl (t, FALSE);
8403 finish_decl (t, NULL_TREE, FALSE);
8405 ffesymbol_hook (s).assign_tree = t;
8407 lineno = old_lineno;
8408 input_filename = old_input_filename;
8413 /* Implement COMMON area in back end.
8415 Because COMMON-based variables can be referenced in the dimension
8416 expressions of dummy (adjustable) arrays, and because dummies
8417 (in the gcc back end) need to be put in the outer binding level
8418 of a function (which has two binding levels, the outer holding
8419 the dummies and the inner holding the other vars), special care
8420 must be taken to handle COMMON areas.
8422 The current strategy is basically to always tell the back end about
8423 the COMMON area as a top-level external reference to just a block
8424 of storage of the master type of that area (e.g. integer, real,
8425 character, whatever -- not a structure). As a distinct action,
8426 if initial values are provided, tell the back end about the area
8427 as a top-level non-external (initialized) area and remember not to
8428 allow further initialization or expansion of the area. Meanwhile,
8429 if no initialization happens at all, tell the back end about
8430 the largest size we've seen declared so the space does get reserved.
8431 (This function doesn't handle all that stuff, but it does some
8432 of the important things.)
8434 Meanwhile, for COMMON variables themselves, just keep creating
8435 references like *((float *) (&common_area + offset)) each time
8436 we reference the variable. In other words, don't make a VAR_DECL
8437 or any kind of component reference (like we used to do before 0.4),
8438 though we might do that as well just for debugging purposes (and
8439 stuff the rtl with the appropriate offset expression). */
8442 ffecom_transform_common_ (ffesymbol s)
8444 ffestorag st = ffesymbol_storage (s);
8445 ffeglobal g = ffesymbol_global (s);
8450 bool is_init = ffestorag_is_init (st);
8452 assert (st != NULL);
8455 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8458 /* First update the size of the area in global terms. */
8460 ffeglobal_size_common (s, ffestorag_size (st));
8462 if (!ffeglobal_common_init (g))
8463 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
8465 cbt = ffeglobal_hook (g);
8467 /* If we already have declared this common block for a previous program
8468 unit, and either we already initialized it or we don't have new
8469 initialization for it, just return what we have without changing it. */
8471 if ((cbt != NULL_TREE)
8473 || !DECL_EXTERNAL (cbt)))
8475 if (st->hook == NULL) ffestorag_set_hook (st, cbt);
8479 /* Process inits. */
8483 if (ffestorag_init (st) != NULL)
8487 /* Set the padding for the expression, so ffecom_expr
8488 knows to insert that many zeros. */
8489 switch (ffebld_op (sexp = ffestorag_init (st)))
8491 case FFEBLD_opCONTER:
8492 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
8495 case FFEBLD_opARRTER:
8496 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8499 case FFEBLD_opACCTER:
8500 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8504 assert ("bad op for cmn init (pad)" == NULL);
8508 init = ffecom_expr (sexp);
8509 if (init == error_mark_node)
8510 { /* Hopefully the back end complained! */
8512 if (cbt != NULL_TREE)
8517 init = error_mark_node;
8522 /* cbtype must be permanently allocated! */
8524 /* Allocate the MAX of the areas so far, seen filewide. */
8525 high = build_int_2 ((ffeglobal_common_size (g)
8526 + ffeglobal_common_pad (g)) - 1, 0);
8527 TREE_TYPE (high) = ffecom_integer_type_node;
8530 cbtype = build_array_type (char_type_node,
8531 build_range_type (integer_type_node,
8535 cbtype = build_array_type (char_type_node, NULL_TREE);
8537 if (cbt == NULL_TREE)
8540 = build_decl (VAR_DECL,
8541 ffecom_get_external_identifier_ (s),
8543 TREE_STATIC (cbt) = 1;
8544 TREE_PUBLIC (cbt) = 1;
8549 TREE_TYPE (cbt) = cbtype;
8551 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8552 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
8554 cbt = start_decl (cbt, TRUE);
8555 if (ffeglobal_hook (g) != NULL)
8556 assert (cbt == ffeglobal_hook (g));
8558 assert (!init || !DECL_EXTERNAL (cbt));
8560 /* Make sure that any type can live in COMMON and be referenced
8561 without getting a bus error. We could pick the most restrictive
8562 alignment of all entities actually placed in the COMMON, but
8563 this seems easy enough. */
8565 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
8566 DECL_USER_ALIGN (cbt) = 0;
8568 if (is_init && (ffestorag_init (st) == NULL))
8569 init = ffecom_init_zero_ (cbt);
8571 finish_decl (cbt, init, TRUE);
8574 ffestorag_set_init (st, ffebld_new_any ());
8578 assert (DECL_SIZE_UNIT (cbt) != NULL_TREE);
8579 assert (TREE_CODE (DECL_SIZE_UNIT (cbt)) == INTEGER_CST);
8580 assert (0 == compare_tree_int (DECL_SIZE_UNIT (cbt),
8581 (ffeglobal_common_size (g)
8582 + ffeglobal_common_pad (g))));
8585 ffeglobal_set_hook (g, cbt);
8587 ffestorag_set_hook (st, cbt);
8589 ffecom_save_tree_forever (cbt);
8592 /* Make master area for local EQUIVALENCE. */
8595 ffecom_transform_equiv_ (ffestorag eqst)
8601 bool is_init = ffestorag_is_init (eqst);
8603 assert (eqst != NULL);
8605 eqt = ffestorag_hook (eqst);
8607 if (eqt != NULL_TREE)
8610 /* Process inits. */
8614 if (ffestorag_init (eqst) != NULL)
8618 /* Set the padding for the expression, so ffecom_expr
8619 knows to insert that many zeros. */
8620 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8622 case FFEBLD_opCONTER:
8623 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8626 case FFEBLD_opARRTER:
8627 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8630 case FFEBLD_opACCTER:
8631 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8635 assert ("bad op for eqv init (pad)" == NULL);
8639 init = ffecom_expr (sexp);
8640 if (init == error_mark_node)
8641 init = NULL_TREE; /* Hopefully the back end complained! */
8644 init = error_mark_node;
8646 else if (ffe_is_init_local_zero ())
8647 init = error_mark_node;
8651 ffecom_member_namelisted_ = FALSE;
8652 ffestorag_drive (ffestorag_list_equivs (eqst),
8653 &ffecom_member_phase1_,
8656 high = build_int_2 ((ffestorag_size (eqst)
8657 + ffestorag_modulo (eqst)) - 1, 0);
8658 TREE_TYPE (high) = ffecom_integer_type_node;
8660 eqtype = build_array_type (char_type_node,
8661 build_range_type (ffecom_integer_type_node,
8662 ffecom_integer_zero_node,
8665 eqt = build_decl (VAR_DECL,
8666 ffecom_get_invented_identifier ("__g77_equiv_%s",
8668 (ffestorag_symbol (eqst))),
8670 DECL_EXTERNAL (eqt) = 0;
8672 || ffecom_member_namelisted_
8673 #ifdef FFECOM_sizeMAXSTACKITEM
8674 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8676 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8677 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8678 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8679 TREE_STATIC (eqt) = 1;
8681 TREE_STATIC (eqt) = 0;
8682 TREE_PUBLIC (eqt) = 0;
8683 TREE_ADDRESSABLE (eqt) = 1; /* Ensure non-register allocation */
8684 DECL_CONTEXT (eqt) = current_function_decl;
8686 DECL_INITIAL (eqt) = error_mark_node;
8688 DECL_INITIAL (eqt) = NULL_TREE;
8690 eqt = start_decl (eqt, FALSE);
8692 /* Make sure that any type can live in EQUIVALENCE and be referenced
8693 without getting a bus error. We could pick the most restrictive
8694 alignment of all entities actually placed in the EQUIVALENCE, but
8695 this seems easy enough. */
8697 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
8698 DECL_USER_ALIGN (eqt) = 0;
8700 if ((!is_init && ffe_is_init_local_zero ())
8701 || (is_init && (ffestorag_init (eqst) == NULL)))
8702 init = ffecom_init_zero_ (eqt);
8704 finish_decl (eqt, init, FALSE);
8707 ffestorag_set_init (eqst, ffebld_new_any ());
8710 assert (TREE_CODE (DECL_SIZE_UNIT (eqt)) == INTEGER_CST);
8711 assert (0 == compare_tree_int (DECL_SIZE_UNIT (eqt),
8712 (ffestorag_size (eqst)
8713 + ffestorag_modulo (eqst))));
8716 ffestorag_set_hook (eqst, eqt);
8718 ffestorag_drive (ffestorag_list_equivs (eqst),
8719 &ffecom_member_phase2_,
8723 /* Implement NAMELIST in back end. See f2c/format.c for more info. */
8726 ffecom_transform_namelist_ (ffesymbol s)
8729 tree nmltype = ffecom_type_namelist_ ();
8737 static int mynumber = 0;
8739 nmlt = build_decl (VAR_DECL,
8740 ffecom_get_invented_identifier ("__g77_namelist_%d",
8743 TREE_STATIC (nmlt) = 1;
8744 DECL_INITIAL (nmlt) = error_mark_node;
8746 nmlt = start_decl (nmlt, FALSE);
8748 /* Process inits. */
8750 i = strlen (ffesymbol_text (s));
8752 high = build_int_2 (i, 0);
8753 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
8755 nameinit = ffecom_build_f2c_string_ (i + 1,
8756 ffesymbol_text (s));
8757 TREE_TYPE (nameinit)
8758 = build_type_variant
8761 build_range_type (ffecom_f2c_ftnlen_type_node,
8762 ffecom_f2c_ftnlen_one_node,
8765 TREE_CONSTANT (nameinit) = 1;
8766 TREE_STATIC (nameinit) = 1;
8767 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
8770 varsinit = ffecom_vardesc_array_ (s);
8771 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
8773 TREE_CONSTANT (varsinit) = 1;
8774 TREE_STATIC (varsinit) = 1;
8779 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
8782 nvarsinit = build_int_2 (i, 0);
8783 TREE_TYPE (nvarsinit) = integer_type_node;
8784 TREE_CONSTANT (nvarsinit) = 1;
8785 TREE_STATIC (nvarsinit) = 1;
8787 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
8788 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
8790 TREE_CHAIN (TREE_CHAIN (nmlinits))
8791 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
8793 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
8794 TREE_CONSTANT (nmlinits) = 1;
8795 TREE_STATIC (nmlinits) = 1;
8797 finish_decl (nmlt, nmlinits, FALSE);
8799 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
8804 /* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
8805 analyzed on the assumption it is calculating a pointer to be
8806 indirected through. It must return the proper decl and offset,
8807 taking into account different units of measurements for offsets. */
8810 ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
8813 switch (TREE_CODE (t))
8817 case NON_LVALUE_EXPR:
8818 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
8822 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
8823 if ((*decl == NULL_TREE)
8824 || (*decl == error_mark_node))
8827 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
8829 /* An offset into COMMON. */
8830 *offset = fold (build (PLUS_EXPR, TREE_TYPE (*offset),
8831 *offset, TREE_OPERAND (t, 1)));
8832 /* Convert offset (presumably in bytes) into canonical units
8833 (presumably bits). */
8834 *offset = size_binop (MULT_EXPR,
8835 convert (bitsizetype, *offset),
8836 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))));
8839 /* Not a COMMON reference, so an unrecognized pattern. */
8840 *decl = error_mark_node;
8845 *offset = bitsize_zero_node;
8849 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
8851 /* A reference to COMMON. */
8852 *decl = TREE_OPERAND (t, 0);
8853 *offset = bitsize_zero_node;
8858 /* Not a COMMON reference, so an unrecognized pattern. */
8859 *decl = error_mark_node;
8864 /* Given a tree that is possibly intended for use as an lvalue, return
8865 information representing a canonical view of that tree as a decl, an
8866 offset into that decl, and a size for the lvalue.
8868 If there's no applicable decl, NULL_TREE is returned for the decl,
8869 and the other fields are left undefined.
8871 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
8872 is returned for the decl, and the other fields are left undefined.
8874 Otherwise, the decl returned currently is either a VAR_DECL or a
8877 The offset returned is always valid, but of course not necessarily
8878 a constant, and not necessarily converted into the appropriate
8879 type, leaving that up to the caller (so as to avoid that overhead
8880 if the decls being looked at are different anyway).
8882 If the size cannot be determined (e.g. an adjustable array),
8883 an ERROR_MARK node is returned for the size. Otherwise, the
8884 size returned is valid, not necessarily a constant, and not
8885 necessarily converted into the appropriate type as with the
8888 Note that the offset and size expressions are expressed in the
8889 base storage units (usually bits) rather than in the units of
8890 the type of the decl, because two decls with different types
8891 might overlap but with apparently non-overlapping array offsets,
8892 whereas converting the array offsets to consistant offsets will
8893 reveal the overlap. */
8896 ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
8899 /* The default path is to report a nonexistant decl. */
8905 switch (TREE_CODE (t))
8908 case IDENTIFIER_NODE:
8917 case TRUNC_DIV_EXPR:
8919 case FLOOR_DIV_EXPR:
8920 case ROUND_DIV_EXPR:
8921 case TRUNC_MOD_EXPR:
8923 case FLOOR_MOD_EXPR:
8924 case ROUND_MOD_EXPR:
8926 case EXACT_DIV_EXPR:
8927 case FIX_TRUNC_EXPR:
8929 case FIX_FLOOR_EXPR:
8930 case FIX_ROUND_EXPR:
8944 case BIT_ANDTC_EXPR:
8946 case TRUTH_ANDIF_EXPR:
8947 case TRUTH_ORIF_EXPR:
8948 case TRUTH_AND_EXPR:
8950 case TRUTH_XOR_EXPR:
8951 case TRUTH_NOT_EXPR:
8971 *offset = bitsize_zero_node;
8972 *size = TYPE_SIZE (TREE_TYPE (t));
8977 tree array = TREE_OPERAND (t, 0);
8978 tree element = TREE_OPERAND (t, 1);
8981 if ((array == NULL_TREE)
8982 || (element == NULL_TREE))
8984 *decl = error_mark_node;
8988 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
8990 if ((*decl == NULL_TREE)
8991 || (*decl == error_mark_node))
8994 /* Calculate ((element - base) * NBBY) + init_offset. */
8995 *offset = fold (build (MINUS_EXPR, TREE_TYPE (element),
8997 TYPE_MIN_VALUE (TYPE_DOMAIN
8998 (TREE_TYPE (array)))));
9000 *offset = size_binop (MULT_EXPR,
9001 convert (bitsizetype, *offset),
9002 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))));
9004 *offset = size_binop (PLUS_EXPR, init_offset, *offset);
9006 *size = TYPE_SIZE (TREE_TYPE (t));
9012 /* Most of this code is to handle references to COMMON. And so
9013 far that is useful only for calling library functions, since
9014 external (user) functions might reference common areas. But
9015 even calling an external function, it's worthwhile to decode
9016 COMMON references because if not storing into COMMON, we don't
9017 want COMMON-based arguments to gratuitously force use of a
9020 *size = TYPE_SIZE (TREE_TYPE (t));
9022 ffecom_tree_canonize_ptr_ (decl, offset,
9023 TREE_OPERAND (t, 0));
9030 case NON_LVALUE_EXPR:
9033 case COND_EXPR: /* More cases than we can handle. */
9035 case REFERENCE_EXPR:
9036 case PREDECREMENT_EXPR:
9037 case PREINCREMENT_EXPR:
9038 case POSTDECREMENT_EXPR:
9039 case POSTINCREMENT_EXPR:
9042 *decl = error_mark_node;
9047 /* Do divide operation appropriate to type of operands. */
9050 ffecom_tree_divide_ (tree tree_type, tree left, tree right,
9051 tree dest_tree, ffebld dest, bool *dest_used,
9054 if ((left == error_mark_node)
9055 || (right == error_mark_node))
9056 return error_mark_node;
9058 switch (TREE_CODE (tree_type))
9061 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9066 if (! optimize_size)
9067 return ffecom_2 (RDIV_EXPR, tree_type,
9073 if (TREE_TYPE (tree_type)
9074 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9075 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9077 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9079 left = ffecom_1 (ADDR_EXPR,
9080 build_pointer_type (TREE_TYPE (left)),
9082 left = build_tree_list (NULL_TREE, left);
9083 right = ffecom_1 (ADDR_EXPR,
9084 build_pointer_type (TREE_TYPE (right)),
9086 right = build_tree_list (NULL_TREE, right);
9087 TREE_CHAIN (left) = right;
9089 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9090 ffecom_gfrt_kindtype (ix),
9091 ffe_is_f2c_library (),
9094 dest_tree, dest, dest_used,
9095 NULL_TREE, TRUE, hook);
9103 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9104 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9105 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9107 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9109 left = ffecom_1 (ADDR_EXPR,
9110 build_pointer_type (TREE_TYPE (left)),
9112 left = build_tree_list (NULL_TREE, left);
9113 right = ffecom_1 (ADDR_EXPR,
9114 build_pointer_type (TREE_TYPE (right)),
9116 right = build_tree_list (NULL_TREE, right);
9117 TREE_CHAIN (left) = right;
9119 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9120 ffecom_gfrt_kindtype (ix),
9121 ffe_is_f2c_library (),
9124 dest_tree, dest, dest_used,
9125 NULL_TREE, TRUE, hook);
9130 return ffecom_2 (RDIV_EXPR, tree_type,
9136 /* Build type info for non-dummy variable. */
9139 ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
9148 type = ffecom_tree_type[bt][kt];
9149 if (bt == FFEINFO_basictypeCHARACTER)
9151 hight = build_int_2 (ffesymbol_size (s), 0);
9152 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
9157 build_range_type (ffecom_f2c_ftnlen_type_node,
9158 ffecom_f2c_ftnlen_one_node,
9160 type = ffecom_check_size_overflow_ (s, type, FALSE);
9163 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9165 if (type == error_mark_node)
9168 dim = ffebld_head (dl);
9169 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
9171 if (ffebld_left (dim) == NULL)
9172 lowt = integer_one_node;
9174 lowt = ffecom_expr (ffebld_left (dim));
9176 if (TREE_CODE (lowt) != INTEGER_CST)
9177 lowt = variable_size (lowt);
9179 assert (ffebld_right (dim) != NULL);
9180 hight = ffecom_expr (ffebld_right (dim));
9182 if (TREE_CODE (hight) != INTEGER_CST)
9183 hight = variable_size (hight);
9185 type = build_array_type (type,
9186 build_range_type (ffecom_integer_type_node,
9188 type = ffecom_check_size_overflow_ (s, type, FALSE);
9194 /* Build Namelist type. */
9197 ffecom_type_namelist_ ()
9199 static tree type = NULL_TREE;
9201 if (type == NULL_TREE)
9203 static tree namefield, varsfield, nvarsfield;
9206 vardesctype = ffecom_type_vardesc_ ();
9208 type = make_node (RECORD_TYPE);
9210 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
9212 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9214 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9215 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9218 TYPE_FIELDS (type) = namefield;
9221 ggc_add_tree_root (&type, 1);
9227 /* Build Vardesc type. */
9230 ffecom_type_vardesc_ ()
9232 static tree type = NULL_TREE;
9233 static tree namefield, addrfield, dimsfield, typefield;
9235 if (type == NULL_TREE)
9237 type = make_node (RECORD_TYPE);
9239 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9241 addrfield = ffecom_decl_field (type, namefield, "addr",
9243 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9244 ffecom_f2c_ptr_to_ftnlen_type_node);
9245 typefield = ffecom_decl_field (type, dimsfield, "type",
9248 TYPE_FIELDS (type) = namefield;
9251 ggc_add_tree_root (&type, 1);
9258 ffecom_vardesc_ (ffebld expr)
9262 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9263 s = ffebld_symter (expr);
9265 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9268 tree vardesctype = ffecom_type_vardesc_ ();
9276 static int mynumber = 0;
9278 var = build_decl (VAR_DECL,
9279 ffecom_get_invented_identifier ("__g77_vardesc_%d",
9282 TREE_STATIC (var) = 1;
9283 DECL_INITIAL (var) = error_mark_node;
9285 var = start_decl (var, FALSE);
9287 /* Process inits. */
9289 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9291 ffesymbol_text (s));
9292 TREE_TYPE (nameinit)
9293 = build_type_variant
9296 build_range_type (integer_type_node,
9298 build_int_2 (i, 0))),
9300 TREE_CONSTANT (nameinit) = 1;
9301 TREE_STATIC (nameinit) = 1;
9302 nameinit = ffecom_1 (ADDR_EXPR,
9303 build_pointer_type (TREE_TYPE (nameinit)),
9306 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
9308 dimsinit = ffecom_vardesc_dims_ (s);
9310 if (typeinit == NULL_TREE)
9312 ffeinfoBasictype bt = ffesymbol_basictype (s);
9313 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9314 int tc = ffecom_f2c_typecode (bt, kt);
9317 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9320 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
9322 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9324 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9326 TREE_CHAIN (TREE_CHAIN (varinits))
9327 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9328 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9329 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
9331 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
9332 TREE_CONSTANT (varinits) = 1;
9333 TREE_STATIC (varinits) = 1;
9335 finish_decl (var, varinits, FALSE);
9337 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
9339 ffesymbol_hook (s).vardesc_tree = var;
9342 return ffesymbol_hook (s).vardesc_tree;
9346 ffecom_vardesc_array_ (ffesymbol s)
9350 tree item = NULL_TREE;
9353 static int mynumber = 0;
9355 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9357 b = ffebld_trail (b), ++i)
9361 t = ffecom_vardesc_ (ffebld_head (b));
9363 if (list == NULL_TREE)
9364 list = item = build_tree_list (NULL_TREE, t);
9367 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9368 item = TREE_CHAIN (item);
9372 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9373 build_range_type (integer_type_node,
9375 build_int_2 (i, 0)));
9376 list = build (CONSTRUCTOR, item, NULL_TREE, list);
9377 TREE_CONSTANT (list) = 1;
9378 TREE_STATIC (list) = 1;
9380 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber++);
9381 var = build_decl (VAR_DECL, var, item);
9382 TREE_STATIC (var) = 1;
9383 DECL_INITIAL (var) = error_mark_node;
9384 var = start_decl (var, FALSE);
9385 finish_decl (var, list, FALSE);
9391 ffecom_vardesc_dims_ (ffesymbol s)
9393 if (ffesymbol_dims (s) == NULL)
9394 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9402 tree item = NULL_TREE;
9406 tree baseoff = NULL_TREE;
9407 static int mynumber = 0;
9409 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9410 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9412 numelem = ffecom_expr (ffesymbol_arraysize (s));
9413 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9416 backlist = NULL_TREE;
9417 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9419 b = ffebld_trail (b), e = ffebld_trail (e))
9425 if (ffebld_trail (b) == NULL)
9429 t = convert (ffecom_f2c_ftnlen_type_node,
9430 ffecom_expr (ffebld_head (e)));
9432 if (list == NULL_TREE)
9433 list = item = build_tree_list (NULL_TREE, t);
9436 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9437 item = TREE_CHAIN (item);
9441 if (ffebld_left (ffebld_head (b)) == NULL)
9442 low = ffecom_integer_one_node;
9444 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9445 low = convert (ffecom_f2c_ftnlen_type_node, low);
9447 back = build_tree_list (low, t);
9448 TREE_CHAIN (back) = backlist;
9452 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9454 if (TREE_VALUE (item) == NULL_TREE)
9455 baseoff = TREE_PURPOSE (item);
9457 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9458 TREE_PURPOSE (item),
9459 ffecom_2 (MULT_EXPR,
9460 ffecom_f2c_ftnlen_type_node,
9465 /* backlist now dead, along with all TREE_PURPOSEs on it. */
9467 baseoff = build_tree_list (NULL_TREE, baseoff);
9468 TREE_CHAIN (baseoff) = list;
9470 numelem = build_tree_list (NULL_TREE, numelem);
9471 TREE_CHAIN (numelem) = baseoff;
9473 numdim = build_tree_list (NULL_TREE, numdim);
9474 TREE_CHAIN (numdim) = numelem;
9476 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9477 build_range_type (integer_type_node,
9480 ((int) ffesymbol_rank (s)
9482 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
9483 TREE_CONSTANT (list) = 1;
9484 TREE_STATIC (list) = 1;
9486 var = ffecom_get_invented_identifier ("__g77_dims_%d", mynumber++);
9487 var = build_decl (VAR_DECL, var, item);
9488 TREE_STATIC (var) = 1;
9489 DECL_INITIAL (var) = error_mark_node;
9490 var = start_decl (var, FALSE);
9491 finish_decl (var, list, FALSE);
9493 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9499 /* Essentially does a "fold (build1 (code, type, node))" while checking
9500 for certain housekeeping things.
9502 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9503 ffecom_1_fn instead. */
9506 ffecom_1 (enum tree_code code, tree type, tree node)
9510 if ((node == error_mark_node)
9511 || (type == error_mark_node))
9512 return error_mark_node;
9514 if (code == ADDR_EXPR)
9516 if (!mark_addressable (node))
9517 assert ("can't mark_addressable this node!" == NULL);
9520 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9525 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
9529 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9534 if (TREE_CODE (type) != RECORD_TYPE)
9536 item = build1 (code, type, node);
9539 node = ffecom_stabilize_aggregate_ (node);
9540 realtype = TREE_TYPE (TYPE_FIELDS (type));
9542 ffecom_2 (COMPLEX_EXPR, type,
9543 ffecom_1 (NEGATE_EXPR, realtype,
9544 ffecom_1 (REALPART_EXPR, realtype,
9546 ffecom_1 (NEGATE_EXPR, realtype,
9547 ffecom_1 (IMAGPART_EXPR, realtype,
9552 item = build1 (code, type, node);
9556 if (TREE_SIDE_EFFECTS (node))
9557 TREE_SIDE_EFFECTS (item) = 1;
9558 if ((code == ADDR_EXPR) && staticp (node))
9559 TREE_CONSTANT (item) = 1;
9563 /* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9564 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9565 does not set TREE_ADDRESSABLE (because calling an inline
9566 function does not mean the function needs to be separately
9570 ffecom_1_fn (tree node)
9575 if (node == error_mark_node)
9576 return error_mark_node;
9578 type = build_type_variant (TREE_TYPE (node),
9579 TREE_READONLY (node),
9580 TREE_THIS_VOLATILE (node));
9581 item = build1 (ADDR_EXPR,
9582 build_pointer_type (type), node);
9583 if (TREE_SIDE_EFFECTS (node))
9584 TREE_SIDE_EFFECTS (item) = 1;
9586 TREE_CONSTANT (item) = 1;
9590 /* Essentially does a "fold (build (code, type, node1, node2))" while
9591 checking for certain housekeeping things. */
9594 ffecom_2 (enum tree_code code, tree type, tree node1,
9599 if ((node1 == error_mark_node)
9600 || (node2 == error_mark_node)
9601 || (type == error_mark_node))
9602 return error_mark_node;
9604 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9606 tree a, b, c, d, realtype;
9609 assert ("no CONJ_EXPR support yet" == NULL);
9610 return error_mark_node;
9613 item = build_tree_list (TYPE_FIELDS (type), node1);
9614 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9615 item = build (CONSTRUCTOR, type, NULL_TREE, item);
9619 if (TREE_CODE (type) != RECORD_TYPE)
9621 item = build (code, type, node1, node2);
9624 node1 = ffecom_stabilize_aggregate_ (node1);
9625 node2 = ffecom_stabilize_aggregate_ (node2);
9626 realtype = TREE_TYPE (TYPE_FIELDS (type));
9628 ffecom_2 (COMPLEX_EXPR, type,
9629 ffecom_2 (PLUS_EXPR, realtype,
9630 ffecom_1 (REALPART_EXPR, realtype,
9632 ffecom_1 (REALPART_EXPR, realtype,
9634 ffecom_2 (PLUS_EXPR, realtype,
9635 ffecom_1 (IMAGPART_EXPR, realtype,
9637 ffecom_1 (IMAGPART_EXPR, realtype,
9642 if (TREE_CODE (type) != RECORD_TYPE)
9644 item = build (code, type, node1, node2);
9647 node1 = ffecom_stabilize_aggregate_ (node1);
9648 node2 = ffecom_stabilize_aggregate_ (node2);
9649 realtype = TREE_TYPE (TYPE_FIELDS (type));
9651 ffecom_2 (COMPLEX_EXPR, type,
9652 ffecom_2 (MINUS_EXPR, realtype,
9653 ffecom_1 (REALPART_EXPR, realtype,
9655 ffecom_1 (REALPART_EXPR, realtype,
9657 ffecom_2 (MINUS_EXPR, realtype,
9658 ffecom_1 (IMAGPART_EXPR, realtype,
9660 ffecom_1 (IMAGPART_EXPR, realtype,
9665 if (TREE_CODE (type) != RECORD_TYPE)
9667 item = build (code, type, node1, node2);
9670 node1 = ffecom_stabilize_aggregate_ (node1);
9671 node2 = ffecom_stabilize_aggregate_ (node2);
9672 realtype = TREE_TYPE (TYPE_FIELDS (type));
9673 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9675 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9677 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9679 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9682 ffecom_2 (COMPLEX_EXPR, type,
9683 ffecom_2 (MINUS_EXPR, realtype,
9684 ffecom_2 (MULT_EXPR, realtype,
9687 ffecom_2 (MULT_EXPR, realtype,
9690 ffecom_2 (PLUS_EXPR, realtype,
9691 ffecom_2 (MULT_EXPR, realtype,
9694 ffecom_2 (MULT_EXPR, realtype,
9700 if ((TREE_CODE (node1) != RECORD_TYPE)
9701 && (TREE_CODE (node2) != RECORD_TYPE))
9703 item = build (code, type, node1, node2);
9706 assert (TREE_CODE (node1) == RECORD_TYPE);
9707 assert (TREE_CODE (node2) == RECORD_TYPE);
9708 node1 = ffecom_stabilize_aggregate_ (node1);
9709 node2 = ffecom_stabilize_aggregate_ (node2);
9710 realtype = TREE_TYPE (TYPE_FIELDS (type));
9712 ffecom_2 (TRUTH_ANDIF_EXPR, type,
9713 ffecom_2 (code, type,
9714 ffecom_1 (REALPART_EXPR, realtype,
9716 ffecom_1 (REALPART_EXPR, realtype,
9718 ffecom_2 (code, type,
9719 ffecom_1 (IMAGPART_EXPR, realtype,
9721 ffecom_1 (IMAGPART_EXPR, realtype,
9726 if ((TREE_CODE (node1) != RECORD_TYPE)
9727 && (TREE_CODE (node2) != RECORD_TYPE))
9729 item = build (code, type, node1, node2);
9732 assert (TREE_CODE (node1) == RECORD_TYPE);
9733 assert (TREE_CODE (node2) == RECORD_TYPE);
9734 node1 = ffecom_stabilize_aggregate_ (node1);
9735 node2 = ffecom_stabilize_aggregate_ (node2);
9736 realtype = TREE_TYPE (TYPE_FIELDS (type));
9738 ffecom_2 (TRUTH_ORIF_EXPR, type,
9739 ffecom_2 (code, type,
9740 ffecom_1 (REALPART_EXPR, realtype,
9742 ffecom_1 (REALPART_EXPR, realtype,
9744 ffecom_2 (code, type,
9745 ffecom_1 (IMAGPART_EXPR, realtype,
9747 ffecom_1 (IMAGPART_EXPR, realtype,
9752 item = build (code, type, node1, node2);
9756 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
9757 TREE_SIDE_EFFECTS (item) = 1;
9761 /* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
9763 ffesymbol s; // the ENTRY point itself
9764 if (ffecom_2pass_advise_entrypoint(s))
9765 // the ENTRY point has been accepted
9767 Does whatever compiler needs to do when it learns about the entrypoint,
9768 like determine the return type of the master function, count the
9769 number of entrypoints, etc. Returns FALSE if the return type is
9770 not compatible with the return type(s) of other entrypoint(s).
9772 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
9773 later (after _finish_progunit) be called with the same entrypoint(s)
9774 as passed to this fn for which TRUE was returned.
9777 Return FALSE if the return type conflicts with previous entrypoints. */
9780 ffecom_2pass_advise_entrypoint (ffesymbol entry)
9782 ffebld list; /* opITEM. */
9783 ffebld mlist; /* opITEM. */
9784 ffebld plist; /* opITEM. */
9785 ffebld arg; /* ffebld_head(opITEM). */
9786 ffebld item; /* opITEM. */
9787 ffesymbol s; /* ffebld_symter(arg). */
9788 ffeinfoBasictype bt = ffesymbol_basictype (entry);
9789 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
9790 ffetargetCharacterSize size = ffesymbol_size (entry);
9793 if (ffecom_num_entrypoints_ == 0)
9794 { /* First entrypoint, make list of main
9795 arglist's dummies. */
9796 assert (ffecom_primary_entry_ != NULL);
9798 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
9799 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
9800 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
9802 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
9804 list = ffebld_trail (list))
9806 arg = ffebld_head (list);
9807 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9808 continue; /* Alternate return or some such thing. */
9809 item = ffebld_new_item (arg, NULL);
9811 ffecom_master_arglist_ = item;
9813 ffebld_set_trail (plist, item);
9818 /* If necessary, scan entry arglist for alternate returns. Do this scan
9819 apparently redundantly (it's done below to UNIONize the arglists) so
9820 that we don't complain about RETURN 1 if an offending ENTRY is the only
9821 one with an alternate return. */
9823 if (!ffecom_is_altreturning_)
9825 for (list = ffesymbol_dummyargs (entry);
9827 list = ffebld_trail (list))
9829 arg = ffebld_head (list);
9830 if (ffebld_op (arg) == FFEBLD_opSTAR)
9832 ffecom_is_altreturning_ = TRUE;
9838 /* Now check type compatibility. */
9840 switch (ffecom_master_bt_)
9842 case FFEINFO_basictypeNONE:
9843 ok = (bt != FFEINFO_basictypeCHARACTER);
9846 case FFEINFO_basictypeCHARACTER:
9848 = (bt == FFEINFO_basictypeCHARACTER)
9849 && (kt == ffecom_master_kt_)
9850 && (size == ffecom_master_size_);
9853 case FFEINFO_basictypeANY:
9854 return FALSE; /* Just don't bother. */
9857 if (bt == FFEINFO_basictypeCHARACTER)
9863 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
9865 ffecom_master_bt_ = FFEINFO_basictypeNONE;
9866 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
9873 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
9874 ffest_ffebad_here_current_stmt (0);
9876 return FALSE; /* Can't handle entrypoint. */
9879 /* Entrypoint type compatible with previous types. */
9881 ++ffecom_num_entrypoints_;
9883 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
9885 for (list = ffesymbol_dummyargs (entry);
9887 list = ffebld_trail (list))
9889 arg = ffebld_head (list);
9890 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9891 continue; /* Alternate return or some such thing. */
9892 s = ffebld_symter (arg);
9893 for (plist = NULL, mlist = ffecom_master_arglist_;
9895 plist = mlist, mlist = ffebld_trail (mlist))
9896 { /* plist points to previous item for easy
9897 appending of arg. */
9898 if (ffebld_symter (ffebld_head (mlist)) == s)
9899 break; /* Already have this arg in the master list. */
9902 continue; /* Already have this arg in the master list. */
9904 /* Append this arg to the master list. */
9906 item = ffebld_new_item (arg, NULL);
9908 ffecom_master_arglist_ = item;
9910 ffebld_set_trail (plist, item);
9916 /* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
9918 ffesymbol s; // the ENTRY point itself
9919 ffecom_2pass_do_entrypoint(s);
9921 Does whatever compiler needs to do to make the entrypoint actually
9922 happen. Must be called for each entrypoint after
9923 ffecom_finish_progunit is called. */
9926 ffecom_2pass_do_entrypoint (ffesymbol entry)
9928 static int mfn_num = 0;
9931 if (mfn_num != ffecom_num_fns_)
9932 { /* First entrypoint for this program unit. */
9934 mfn_num = ffecom_num_fns_;
9935 ffecom_do_entry_ (ffecom_primary_entry_, 0);
9940 --ffecom_num_entrypoints_;
9942 ffecom_do_entry_ (entry, ent_num);
9945 /* Essentially does a "fold (build (code, type, node1, node2))" while
9946 checking for certain housekeeping things. Always sets
9947 TREE_SIDE_EFFECTS. */
9950 ffecom_2s (enum tree_code code, tree type, tree node1,
9955 if ((node1 == error_mark_node)
9956 || (node2 == error_mark_node)
9957 || (type == error_mark_node))
9958 return error_mark_node;
9960 item = build (code, type, node1, node2);
9961 TREE_SIDE_EFFECTS (item) = 1;
9965 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
9966 checking for certain housekeeping things. */
9969 ffecom_3 (enum tree_code code, tree type, tree node1,
9970 tree node2, tree node3)
9974 if ((node1 == error_mark_node)
9975 || (node2 == error_mark_node)
9976 || (node3 == error_mark_node)
9977 || (type == error_mark_node))
9978 return error_mark_node;
9980 item = build (code, type, node1, node2, node3);
9981 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
9982 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
9983 TREE_SIDE_EFFECTS (item) = 1;
9987 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
9988 checking for certain housekeeping things. Always sets
9989 TREE_SIDE_EFFECTS. */
9992 ffecom_3s (enum tree_code code, tree type, tree node1,
9993 tree node2, tree node3)
9997 if ((node1 == error_mark_node)
9998 || (node2 == error_mark_node)
9999 || (node3 == error_mark_node)
10000 || (type == error_mark_node))
10001 return error_mark_node;
10003 item = build (code, type, node1, node2, node3);
10004 TREE_SIDE_EFFECTS (item) = 1;
10005 return fold (item);
10008 /* ffecom_arg_expr -- Transform argument expr into gcc tree
10010 See use by ffecom_list_expr.
10012 If expression is NULL, returns an integer zero tree. If it is not
10013 a CHARACTER expression, returns whatever ffecom_expr
10014 returns and sets the length return value to NULL_TREE. Otherwise
10015 generates code to evaluate the character expression, returns the proper
10016 pointer to the result, but does NOT set the length return value to a tree
10017 that specifies the length of the result. (In other words, the length
10018 variable is always set to NULL_TREE, because a length is never passed.)
10021 Don't set returned length, since nobody needs it (yet; someday if
10022 we allow CHARACTER*(*) dummies to statement functions, we'll need
10026 ffecom_arg_expr (ffebld expr, tree *length)
10030 *length = NULL_TREE;
10033 return integer_zero_node;
10035 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10036 return ffecom_expr (expr);
10038 return ffecom_arg_ptr_to_expr (expr, &ign);
10041 /* Transform expression into constant argument-pointer-to-expression tree.
10043 If the expression can be transformed into a argument-pointer-to-expression
10044 tree that is constant, that is done, and the tree returned. Else
10045 NULL_TREE is returned.
10047 That way, a caller can attempt to provide compile-time initialization
10048 of a variable and, if that fails, *then* choose to start a new block
10049 and resort to using temporaries, as appropriate. */
10052 ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10055 return integer_zero_node;
10057 if (ffebld_op (expr) == FFEBLD_opANY)
10060 *length = error_mark_node;
10061 return error_mark_node;
10064 if (ffebld_arity (expr) == 0
10065 && (ffebld_op (expr) != FFEBLD_opSYMTER
10066 || ffebld_where (expr) == FFEINFO_whereCOMMON
10067 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10068 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10072 t = ffecom_arg_ptr_to_expr (expr, length);
10073 assert (TREE_CONSTANT (t));
10074 assert (! length || TREE_CONSTANT (*length));
10079 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10080 *length = build_int_2 (ffebld_size (expr), 0);
10082 *length = NULL_TREE;
10086 /* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
10088 See use by ffecom_list_ptr_to_expr.
10090 If expression is NULL, returns an integer zero tree. If it is not
10091 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10092 returns and sets the length return value to NULL_TREE. Otherwise
10093 generates code to evaluate the character expression, returns the proper
10094 pointer to the result, AND sets the length return value to a tree that
10095 specifies the length of the result.
10097 If the length argument is NULL, this is a slightly special
10098 case of building a FORMAT expression, that is, an expression that
10099 will be used at run time without regard to length. For the current
10100 implementation, which uses the libf2c library, this means it is nice
10101 to append a null byte to the end of the expression, where feasible,
10102 to make sure any diagnostic about the FORMAT string terminates at
10105 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10106 length argument. This might even be seen as a feature, if a null
10107 byte can always be appended. */
10110 ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
10114 ffecomConcatList_ catlist;
10116 if (length != NULL)
10117 *length = NULL_TREE;
10120 return integer_zero_node;
10122 switch (ffebld_op (expr))
10124 case FFEBLD_opPERCENT_VAL:
10125 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10126 return ffecom_expr (ffebld_left (expr));
10131 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10132 if (temp_exp == error_mark_node)
10133 return error_mark_node;
10135 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10139 case FFEBLD_opPERCENT_REF:
10140 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10141 return ffecom_ptr_to_expr (ffebld_left (expr));
10142 if (length != NULL)
10144 ign_length = NULL_TREE;
10145 length = &ign_length;
10147 expr = ffebld_left (expr);
10150 case FFEBLD_opPERCENT_DESCR:
10151 switch (ffeinfo_basictype (ffebld_info (expr)))
10153 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10154 case FFEINFO_basictypeHOLLERITH:
10156 case FFEINFO_basictypeCHARACTER:
10157 break; /* Passed by descriptor anyway. */
10160 item = ffecom_ptr_to_expr (expr);
10161 if (item != error_mark_node)
10162 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
10171 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10172 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10173 && (length != NULL))
10174 { /* Pass Hollerith by descriptor. */
10175 ffetargetHollerith h;
10177 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10178 h = ffebld_cu_val_hollerith (ffebld_constant_union
10179 (ffebld_conter (expr)));
10181 = build_int_2 (h.length, 0);
10182 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10186 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10187 return ffecom_ptr_to_expr (expr);
10189 assert (ffeinfo_kindtype (ffebld_info (expr))
10190 == FFEINFO_kindtypeCHARACTER1);
10192 while (ffebld_op (expr) == FFEBLD_opPAREN)
10193 expr = ffebld_left (expr);
10195 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10196 switch (ffecom_concat_list_count_ (catlist))
10198 case 0: /* Shouldn't happen, but in case it does... */
10199 if (length != NULL)
10201 *length = ffecom_f2c_ftnlen_zero_node;
10202 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10204 ffecom_concat_list_kill_ (catlist);
10205 return null_pointer_node;
10207 case 1: /* The (fairly) easy case. */
10208 if (length == NULL)
10209 ffecom_char_args_with_null_ (&item, &ign_length,
10210 ffecom_concat_list_expr_ (catlist, 0));
10212 ffecom_char_args_ (&item, length,
10213 ffecom_concat_list_expr_ (catlist, 0));
10214 ffecom_concat_list_kill_ (catlist);
10215 assert (item != NULL_TREE);
10218 default: /* Must actually concatenate things. */
10223 int count = ffecom_concat_list_count_ (catlist);
10234 ffetargetCharacterSize sz;
10236 sz = ffecom_concat_list_maxlen_ (catlist);
10238 assert (sz != FFETARGET_charactersizeNONE);
10243 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10244 FFETARGET_charactersizeNONE, count, TRUE);
10247 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10248 FFETARGET_charactersizeNONE, count, TRUE);
10249 temporary = ffecom_push_tempvar (char_type_node,
10255 hook = ffebld_nonter_hook (expr);
10257 assert (TREE_CODE (hook) == TREE_VEC);
10258 assert (TREE_VEC_LENGTH (hook) == 3);
10259 length_array = lengths = TREE_VEC_ELT (hook, 0);
10260 item_array = items = TREE_VEC_ELT (hook, 1);
10261 temporary = TREE_VEC_ELT (hook, 2);
10265 known_length = ffecom_f2c_ftnlen_zero_node;
10267 for (i = 0; i < count; ++i)
10270 && (length == NULL))
10271 ffecom_char_args_with_null_ (&citem, &clength,
10272 ffecom_concat_list_expr_ (catlist, i));
10274 ffecom_char_args_ (&citem, &clength,
10275 ffecom_concat_list_expr_ (catlist, i));
10276 if ((citem == error_mark_node)
10277 || (clength == error_mark_node))
10279 ffecom_concat_list_kill_ (catlist);
10280 *length = error_mark_node;
10281 return error_mark_node;
10285 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10286 ffecom_modify (void_type_node,
10287 ffecom_2 (ARRAY_REF,
10288 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10290 build_int_2 (i, 0)),
10293 clength = ffecom_save_tree (clength);
10294 if (length != NULL)
10296 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10300 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10301 ffecom_modify (void_type_node,
10302 ffecom_2 (ARRAY_REF,
10303 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10305 build_int_2 (i, 0)),
10310 temporary = ffecom_1 (ADDR_EXPR,
10311 build_pointer_type (TREE_TYPE (temporary)),
10314 item = build_tree_list (NULL_TREE, temporary);
10316 = build_tree_list (NULL_TREE,
10317 ffecom_1 (ADDR_EXPR,
10318 build_pointer_type (TREE_TYPE (items)),
10320 TREE_CHAIN (TREE_CHAIN (item))
10321 = build_tree_list (NULL_TREE,
10322 ffecom_1 (ADDR_EXPR,
10323 build_pointer_type (TREE_TYPE (lengths)),
10325 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10328 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10329 convert (ffecom_f2c_ftnlen_type_node,
10330 build_int_2 (count, 0))));
10331 num = build_int_2 (sz, 0);
10332 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10333 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10334 = build_tree_list (NULL_TREE, num);
10336 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
10337 TREE_SIDE_EFFECTS (item) = 1;
10338 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10342 if (length != NULL)
10343 *length = known_length;
10346 ffecom_concat_list_kill_ (catlist);
10347 assert (item != NULL_TREE);
10351 /* Generate call to run-time function.
10353 The first arg is the GNU Fortran Run-Time function index, the second
10354 arg is the list of arguments to pass to it. Returned is the expression
10355 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10356 result (which may be void). */
10359 ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
10361 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10362 ffecom_gfrt_kindtype (ix),
10363 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10364 NULL_TREE, args, NULL_TREE, NULL,
10365 NULL, NULL_TREE, TRUE, hook);
10368 /* Transform constant-union to tree. */
10371 ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10372 ffeinfoKindtype kt, tree tree_type)
10378 case FFEINFO_basictypeINTEGER:
10384 #if FFETARGET_okINTEGER1
10385 case FFEINFO_kindtypeINTEGER1:
10386 val = ffebld_cu_val_integer1 (*cu);
10390 #if FFETARGET_okINTEGER2
10391 case FFEINFO_kindtypeINTEGER2:
10392 val = ffebld_cu_val_integer2 (*cu);
10396 #if FFETARGET_okINTEGER3
10397 case FFEINFO_kindtypeINTEGER3:
10398 val = ffebld_cu_val_integer3 (*cu);
10402 #if FFETARGET_okINTEGER4
10403 case FFEINFO_kindtypeINTEGER4:
10404 val = ffebld_cu_val_integer4 (*cu);
10409 assert ("bad INTEGER constant kind type" == NULL);
10410 /* Fall through. */
10411 case FFEINFO_kindtypeANY:
10412 return error_mark_node;
10414 item = build_int_2 (val, (val < 0) ? -1 : 0);
10415 TREE_TYPE (item) = tree_type;
10419 case FFEINFO_basictypeLOGICAL:
10425 #if FFETARGET_okLOGICAL1
10426 case FFEINFO_kindtypeLOGICAL1:
10427 val = ffebld_cu_val_logical1 (*cu);
10431 #if FFETARGET_okLOGICAL2
10432 case FFEINFO_kindtypeLOGICAL2:
10433 val = ffebld_cu_val_logical2 (*cu);
10437 #if FFETARGET_okLOGICAL3
10438 case FFEINFO_kindtypeLOGICAL3:
10439 val = ffebld_cu_val_logical3 (*cu);
10443 #if FFETARGET_okLOGICAL4
10444 case FFEINFO_kindtypeLOGICAL4:
10445 val = ffebld_cu_val_logical4 (*cu);
10450 assert ("bad LOGICAL constant kind type" == NULL);
10451 /* Fall through. */
10452 case FFEINFO_kindtypeANY:
10453 return error_mark_node;
10455 item = build_int_2 (val, (val < 0) ? -1 : 0);
10456 TREE_TYPE (item) = tree_type;
10460 case FFEINFO_basictypeREAL:
10462 REAL_VALUE_TYPE val;
10466 #if FFETARGET_okREAL1
10467 case FFEINFO_kindtypeREAL1:
10468 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10472 #if FFETARGET_okREAL2
10473 case FFEINFO_kindtypeREAL2:
10474 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10478 #if FFETARGET_okREAL3
10479 case FFEINFO_kindtypeREAL3:
10480 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10484 #if FFETARGET_okREAL4
10485 case FFEINFO_kindtypeREAL4:
10486 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10491 assert ("bad REAL constant kind type" == NULL);
10492 /* Fall through. */
10493 case FFEINFO_kindtypeANY:
10494 return error_mark_node;
10496 item = build_real (tree_type, val);
10500 case FFEINFO_basictypeCOMPLEX:
10502 REAL_VALUE_TYPE real;
10503 REAL_VALUE_TYPE imag;
10504 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
10508 #if FFETARGET_okCOMPLEX1
10509 case FFEINFO_kindtypeREAL1:
10510 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10511 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10515 #if FFETARGET_okCOMPLEX2
10516 case FFEINFO_kindtypeREAL2:
10517 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10518 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10522 #if FFETARGET_okCOMPLEX3
10523 case FFEINFO_kindtypeREAL3:
10524 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10525 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10529 #if FFETARGET_okCOMPLEX4
10530 case FFEINFO_kindtypeREAL4:
10531 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10532 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10537 assert ("bad REAL constant kind type" == NULL);
10538 /* Fall through. */
10539 case FFEINFO_kindtypeANY:
10540 return error_mark_node;
10542 item = ffecom_build_complex_constant_ (tree_type,
10543 build_real (el_type, real),
10544 build_real (el_type, imag));
10548 case FFEINFO_basictypeCHARACTER:
10549 { /* Happens only in DATA and similar contexts. */
10550 ffetargetCharacter1 val;
10554 #if FFETARGET_okCHARACTER1
10555 case FFEINFO_kindtypeLOGICAL1:
10556 val = ffebld_cu_val_character1 (*cu);
10561 assert ("bad CHARACTER constant kind type" == NULL);
10562 /* Fall through. */
10563 case FFEINFO_kindtypeANY:
10564 return error_mark_node;
10566 item = build_string (ffetarget_length_character1 (val),
10567 ffetarget_text_character1 (val));
10569 = build_type_variant (build_array_type (char_type_node,
10571 (integer_type_node,
10574 (ffetarget_length_character1
10580 case FFEINFO_basictypeHOLLERITH:
10582 ffetargetHollerith h;
10584 h = ffebld_cu_val_hollerith (*cu);
10586 /* If not at least as wide as default INTEGER, widen it. */
10587 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10588 item = build_string (h.length, h.text);
10591 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
10593 memcpy (str, h.text, h.length);
10594 memset (&str[h.length], ' ',
10595 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10597 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10601 = build_type_variant (build_array_type (char_type_node,
10603 (integer_type_node,
10611 case FFEINFO_basictypeTYPELESS:
10613 ffetargetInteger1 ival;
10614 ffetargetTypeless tless;
10617 tless = ffebld_cu_val_typeless (*cu);
10618 error = ffetarget_convert_integer1_typeless (&ival, tless);
10619 assert (error == FFEBAD);
10621 item = build_int_2 ((int) ival, 0);
10626 assert ("not yet on constant type" == NULL);
10627 /* Fall through. */
10628 case FFEINFO_basictypeANY:
10629 return error_mark_node;
10632 TREE_CONSTANT (item) = 1;
10637 /* Transform expression into constant tree.
10639 If the expression can be transformed into a tree that is constant,
10640 that is done, and the tree returned. Else NULL_TREE is returned.
10642 That way, a caller can attempt to provide compile-time initialization
10643 of a variable and, if that fails, *then* choose to start a new block
10644 and resort to using temporaries, as appropriate. */
10647 ffecom_const_expr (ffebld expr)
10650 return integer_zero_node;
10652 if (ffebld_op (expr) == FFEBLD_opANY)
10653 return error_mark_node;
10655 if (ffebld_arity (expr) == 0
10656 && (ffebld_op (expr) != FFEBLD_opSYMTER
10658 /* ~~Enable once common/equivalence is handled properly? */
10659 || ffebld_where (expr) == FFEINFO_whereCOMMON
10661 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10662 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10666 t = ffecom_expr (expr);
10667 assert (TREE_CONSTANT (t));
10674 /* Handy way to make a field in a struct/union. */
10677 ffecom_decl_field (tree context, tree prevfield,
10678 const char *name, tree type)
10682 field = build_decl (FIELD_DECL, get_identifier (name), type);
10683 DECL_CONTEXT (field) = context;
10684 DECL_ALIGN (field) = 0;
10685 DECL_USER_ALIGN (field) = 0;
10686 if (prevfield != NULL_TREE)
10687 TREE_CHAIN (prevfield) = field;
10693 ffecom_close_include (FILE *f)
10695 ffecom_close_include_ (f);
10699 ffecom_decode_include_option (char *spec)
10701 return ffecom_decode_include_option_ (spec);
10704 /* End a compound statement (block). */
10707 ffecom_end_compstmt (void)
10709 return bison_rule_compstmt_ ();
10712 /* ffecom_end_transition -- Perform end transition on all symbols
10714 ffecom_end_transition();
10716 Calls ffecom_sym_end_transition for each global and local symbol. */
10719 ffecom_end_transition ()
10723 if (ffe_is_ffedebug ())
10724 fprintf (dmpout, "; end_stmt_transition\n");
10726 ffecom_list_blockdata_ = NULL;
10727 ffecom_list_common_ = NULL;
10729 ffesymbol_drive (ffecom_sym_end_transition);
10730 if (ffe_is_ffedebug ())
10732 ffestorag_report ();
10735 ffecom_start_progunit_ ();
10737 for (item = ffecom_list_blockdata_;
10739 item = ffebld_trail (item))
10746 static int number = 0;
10748 callee = ffebld_head (item);
10749 s = ffebld_symter (callee);
10750 t = ffesymbol_hook (s).decl_tree;
10751 if (t == NULL_TREE)
10753 s = ffecom_sym_transform_ (s);
10754 t = ffesymbol_hook (s).decl_tree;
10757 dt = build_pointer_type (TREE_TYPE (t));
10759 var = build_decl (VAR_DECL,
10760 ffecom_get_invented_identifier ("__g77_forceload_%d",
10763 DECL_EXTERNAL (var) = 0;
10764 TREE_STATIC (var) = 1;
10765 TREE_PUBLIC (var) = 0;
10766 DECL_INITIAL (var) = error_mark_node;
10767 TREE_USED (var) = 1;
10769 var = start_decl (var, FALSE);
10771 t = ffecom_1 (ADDR_EXPR, dt, t);
10773 finish_decl (var, t, FALSE);
10776 /* This handles any COMMON areas that weren't referenced but have, for
10777 example, important initial data. */
10779 for (item = ffecom_list_common_;
10781 item = ffebld_trail (item))
10782 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
10784 ffecom_list_common_ = NULL;
10787 /* ffecom_exec_transition -- Perform exec transition on all symbols
10789 ffecom_exec_transition();
10791 Calls ffecom_sym_exec_transition for each global and local symbol.
10792 Make sure error updating not inhibited. */
10795 ffecom_exec_transition ()
10799 if (ffe_is_ffedebug ())
10800 fprintf (dmpout, "; exec_stmt_transition\n");
10802 inhibited = ffebad_inhibit ();
10803 ffebad_set_inhibit (FALSE);
10805 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
10806 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
10807 if (ffe_is_ffedebug ())
10809 ffestorag_report ();
10813 ffebad_set_inhibit (TRUE);
10816 /* Handle assignment statement.
10818 Convert dest and source using ffecom_expr, then join them
10819 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
10822 ffecom_expand_let_stmt (ffebld dest, ffebld source)
10829 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
10834 /* This attempts to replicate the test below, but must not be
10835 true when the test below is false. (Always err on the side
10836 of creating unused temporaries, to avoid ICEs.) */
10837 if (ffebld_op (dest) != FFEBLD_opSYMTER
10838 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
10839 && (TREE_CODE (dest_tree) != VAR_DECL
10840 || TREE_ADDRESSABLE (dest_tree))))
10842 ffecom_prepare_expr_ (source, dest);
10847 ffecom_prepare_expr_ (source, NULL);
10851 ffecom_prepare_expr_w (NULL_TREE, dest);
10853 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
10854 create a temporary through which the assignment is to take place,
10855 since MODIFY_EXPR doesn't handle partial overlap properly. */
10856 if (ffebld_basictype (dest) == FFEINFO_basictypeCOMPLEX
10857 && ffecom_possible_partial_overlap_ (dest, source))
10859 assign_temp = ffecom_make_tempvar ("complex_let",
10861 [ffebld_basictype (dest)]
10862 [ffebld_kindtype (dest)],
10863 FFETARGET_charactersizeNONE,
10867 assign_temp = NULL_TREE;
10869 ffecom_prepare_end ();
10871 dest_tree = ffecom_expr_w (NULL_TREE, dest);
10872 if (dest_tree == error_mark_node)
10875 if ((TREE_CODE (dest_tree) != VAR_DECL)
10876 || TREE_ADDRESSABLE (dest_tree))
10877 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
10881 assert (! dest_used);
10883 source_tree = ffecom_expr (source);
10885 if (source_tree == error_mark_node)
10889 expr_tree = source_tree;
10890 else if (assign_temp)
10893 /* The back end understands a conceptual move (evaluate source;
10894 store into dest), so use that, in case it can determine
10895 that it is going to use, say, two registers as temporaries
10896 anyway. So don't use the temp (and someday avoid generating
10897 it, once this code starts triggering regularly). */
10898 expr_tree = ffecom_2s (MOVE_EXPR, void_type_node,
10902 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10905 expand_expr_stmt (expr_tree);
10906 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10912 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10916 expand_expr_stmt (expr_tree);
10920 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
10921 ffecom_prepare_expr_w (NULL_TREE, dest);
10923 ffecom_prepare_end ();
10925 ffecom_char_args_ (&dest_tree, &dest_length, dest);
10926 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
10930 /* ffecom_expr -- Transform expr into gcc tree
10933 ffebld expr; // FFE expression.
10934 tree = ffecom_expr(expr);
10936 Recursive descent on expr while making corresponding tree nodes and
10937 attaching type info and such. */
10940 ffecom_expr (ffebld expr)
10942 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
10945 /* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
10948 ffecom_expr_assign (ffebld expr)
10950 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10953 /* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
10956 ffecom_expr_assign_w (ffebld expr)
10958 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10961 /* Transform expr for use as into read/write tree and stabilize the
10962 reference. Not for use on CHARACTER expressions.
10964 Recursive descent on expr while making corresponding tree nodes and
10965 attaching type info and such. */
10968 ffecom_expr_rw (tree type, ffebld expr)
10970 assert (expr != NULL);
10971 /* Different target types not yet supported. */
10972 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
10974 return stabilize_reference (ffecom_expr (expr));
10977 /* Transform expr for use as into write tree and stabilize the
10978 reference. Not for use on CHARACTER expressions.
10980 Recursive descent on expr while making corresponding tree nodes and
10981 attaching type info and such. */
10984 ffecom_expr_w (tree type, ffebld expr)
10986 assert (expr != NULL);
10987 /* Different target types not yet supported. */
10988 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
10990 return stabilize_reference (ffecom_expr (expr));
10993 /* Do global stuff. */
10996 ffecom_finish_compile ()
10998 assert (ffecom_outer_function_decl_ == NULL_TREE);
10999 assert (current_function_decl == NULL_TREE);
11001 ffeglobal_drive (ffecom_finish_global_);
11004 /* Public entry point for front end to access finish_decl. */
11007 ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11009 assert (!is_top_level);
11010 finish_decl (decl, init, FALSE);
11013 /* Finish a program unit. */
11016 ffecom_finish_progunit ()
11018 ffecom_end_compstmt ();
11020 ffecom_previous_function_decl_ = current_function_decl;
11021 ffecom_which_entrypoint_decl_ = NULL_TREE;
11023 finish_function (0);
11026 /* Wrapper for get_identifier. pattern is sprintf-like. */
11029 ffecom_get_invented_identifier (const char *pattern, ...)
11035 va_start (ap, pattern);
11036 if (vasprintf (&nam, pattern, ap) == 0)
11039 decl = get_identifier (nam);
11041 IDENTIFIER_INVENTED (decl) = 1;
11046 ffecom_gfrt_basictype (ffecomGfrt gfrt)
11048 assert (gfrt < FFECOM_gfrt);
11050 switch (ffecom_gfrt_type_[gfrt])
11052 case FFECOM_rttypeVOID_:
11053 case FFECOM_rttypeVOIDSTAR_:
11054 return FFEINFO_basictypeNONE;
11056 case FFECOM_rttypeFTNINT_:
11057 return FFEINFO_basictypeINTEGER;
11059 case FFECOM_rttypeINTEGER_:
11060 return FFEINFO_basictypeINTEGER;
11062 case FFECOM_rttypeLONGINT_:
11063 return FFEINFO_basictypeINTEGER;
11065 case FFECOM_rttypeLOGICAL_:
11066 return FFEINFO_basictypeLOGICAL;
11068 case FFECOM_rttypeREAL_F2C_:
11069 case FFECOM_rttypeREAL_GNU_:
11070 return FFEINFO_basictypeREAL;
11072 case FFECOM_rttypeCOMPLEX_F2C_:
11073 case FFECOM_rttypeCOMPLEX_GNU_:
11074 return FFEINFO_basictypeCOMPLEX;
11076 case FFECOM_rttypeDOUBLE_:
11077 case FFECOM_rttypeDOUBLEREAL_:
11078 return FFEINFO_basictypeREAL;
11080 case FFECOM_rttypeDBLCMPLX_F2C_:
11081 case FFECOM_rttypeDBLCMPLX_GNU_:
11082 return FFEINFO_basictypeCOMPLEX;
11084 case FFECOM_rttypeCHARACTER_:
11085 return FFEINFO_basictypeCHARACTER;
11088 return FFEINFO_basictypeANY;
11093 ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11095 assert (gfrt < FFECOM_gfrt);
11097 switch (ffecom_gfrt_type_[gfrt])
11099 case FFECOM_rttypeVOID_:
11100 case FFECOM_rttypeVOIDSTAR_:
11101 return FFEINFO_kindtypeNONE;
11103 case FFECOM_rttypeFTNINT_:
11104 return FFEINFO_kindtypeINTEGER1;
11106 case FFECOM_rttypeINTEGER_:
11107 return FFEINFO_kindtypeINTEGER1;
11109 case FFECOM_rttypeLONGINT_:
11110 return FFEINFO_kindtypeINTEGER4;
11112 case FFECOM_rttypeLOGICAL_:
11113 return FFEINFO_kindtypeLOGICAL1;
11115 case FFECOM_rttypeREAL_F2C_:
11116 case FFECOM_rttypeREAL_GNU_:
11117 return FFEINFO_kindtypeREAL1;
11119 case FFECOM_rttypeCOMPLEX_F2C_:
11120 case FFECOM_rttypeCOMPLEX_GNU_:
11121 return FFEINFO_kindtypeREAL1;
11123 case FFECOM_rttypeDOUBLE_:
11124 case FFECOM_rttypeDOUBLEREAL_:
11125 return FFEINFO_kindtypeREAL2;
11127 case FFECOM_rttypeDBLCMPLX_F2C_:
11128 case FFECOM_rttypeDBLCMPLX_GNU_:
11129 return FFEINFO_kindtypeREAL2;
11131 case FFECOM_rttypeCHARACTER_:
11132 return FFEINFO_kindtypeCHARACTER1;
11135 return FFEINFO_kindtypeANY;
11149 tree double_ftype_double;
11150 tree float_ftype_float;
11151 tree ldouble_ftype_ldouble;
11152 tree ffecom_tree_ptr_to_fun_type_void;
11154 /* This block of code comes from the now-obsolete cktyps.c. It checks
11155 whether the compiler environment is buggy in known ways, some of which
11156 would, if not explicitly checked here, result in subtle bugs in g77. */
11158 if (ffe_is_do_internal_checks ())
11160 static const char names[][12]
11162 {"bar", "bletch", "foo", "foobar"};
11167 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
11168 (int (*)(const void *, const void *)) strcmp);
11169 if (name != &names[0][2])
11171 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11176 ul = strtoul ("123456789", NULL, 10);
11177 if (ul != 123456789L)
11179 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11180 in proj.h" == NULL);
11184 fl = atof ("56.789");
11185 if ((fl < 56.788) || (fl > 56.79))
11187 assert ("atof not type double, fix your #include <stdio.h>"
11193 ffecom_outer_function_decl_ = NULL_TREE;
11194 current_function_decl = NULL_TREE;
11195 named_labels = NULL_TREE;
11196 current_binding_level = NULL_BINDING_LEVEL;
11197 free_binding_level = NULL_BINDING_LEVEL;
11198 /* Make the binding_level structure for global names. */
11200 global_binding_level = current_binding_level;
11201 current_binding_level->prep_state = 2;
11203 build_common_tree_nodes (1);
11205 /* Define `int' and `char' first so that dbx will output them first. */
11206 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11207 integer_type_node));
11208 /* CHARACTER*1 is unsigned in ICHAR contexts. */
11209 char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
11210 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11212 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11213 long_integer_type_node));
11214 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11215 unsigned_type_node));
11216 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11217 long_unsigned_type_node));
11218 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11219 long_long_integer_type_node));
11220 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11221 long_long_unsigned_type_node));
11222 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11223 short_integer_type_node));
11224 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11225 short_unsigned_type_node));
11227 /* Set the sizetype before we make other types. This *should* be the
11228 first type we create. */
11231 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
11232 ffecom_typesize_pointer_
11233 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype)) / BITS_PER_UNIT;
11235 build_common_tree_nodes_2 (0);
11237 /* Define both `signed char' and `unsigned char'. */
11238 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11239 signed_char_type_node));
11241 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11242 unsigned_char_type_node));
11244 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11246 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11247 double_type_node));
11248 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11249 long_double_type_node));
11251 /* For now, override what build_common_tree_nodes has done. */
11252 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
11253 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11254 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11255 complex_long_double_type_node
11256 = ffecom_make_complex_type_ (long_double_type_node);
11258 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11259 complex_integer_type_node));
11260 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11261 complex_float_type_node));
11262 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11263 complex_double_type_node));
11264 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11265 complex_long_double_type_node));
11267 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11269 /* We are not going to have real types in C with less than byte alignment,
11270 so we might as well not have any types that claim to have it. */
11271 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
11272 TYPE_USER_ALIGN (void_type_node) = 0;
11274 string_type_node = build_pointer_type (char_type_node);
11276 ffecom_tree_fun_type_void
11277 = build_function_type (void_type_node, NULL_TREE);
11279 ffecom_tree_ptr_to_fun_type_void
11280 = build_pointer_type (ffecom_tree_fun_type_void);
11282 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
11285 = build_function_type (float_type_node,
11286 tree_cons (NULL_TREE, float_type_node, endlink));
11288 double_ftype_double
11289 = build_function_type (double_type_node,
11290 tree_cons (NULL_TREE, double_type_node, endlink));
11292 ldouble_ftype_ldouble
11293 = build_function_type (long_double_type_node,
11294 tree_cons (NULL_TREE, long_double_type_node,
11297 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11298 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11300 ffecom_tree_type[i][j] = NULL_TREE;
11301 ffecom_tree_fun_type[i][j] = NULL_TREE;
11302 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11303 ffecom_f2c_typecode_[i][j] = -1;
11306 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11307 to size FLOAT_TYPE_SIZE because they have to be the same size as
11308 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11309 Compiler options and other such stuff that change the ways these
11310 types are set should not affect this particular setup. */
11312 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11313 = t = make_signed_type (FLOAT_TYPE_SIZE);
11314 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11316 type = ffetype_new ();
11318 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11320 ffetype_set_ams (type,
11321 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11322 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11323 ffetype_set_star (base_type,
11324 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11326 ffetype_set_kind (base_type, 1, type);
11327 ffecom_typesize_integer1_ = ffetype_size (type);
11328 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
11330 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11331 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11332 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11335 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11336 = t = make_signed_type (CHAR_TYPE_SIZE);
11337 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11339 type = ffetype_new ();
11340 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11342 ffetype_set_ams (type,
11343 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11344 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11345 ffetype_set_star (base_type,
11346 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11348 ffetype_set_kind (base_type, 3, type);
11349 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
11351 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11352 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11353 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11356 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11357 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11358 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11360 type = ffetype_new ();
11361 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11363 ffetype_set_ams (type,
11364 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11365 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11366 ffetype_set_star (base_type,
11367 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11369 ffetype_set_kind (base_type, 6, type);
11370 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
11372 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11373 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11374 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11377 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11378 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11379 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11381 type = ffetype_new ();
11382 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11384 ffetype_set_ams (type,
11385 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11386 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11387 ffetype_set_star (base_type,
11388 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11390 ffetype_set_kind (base_type, 2, type);
11391 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
11393 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11394 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11395 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11399 if (ffe_is_do_internal_checks ()
11400 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11401 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11402 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11403 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
11405 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11410 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11411 = t = make_signed_type (FLOAT_TYPE_SIZE);
11412 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11414 type = ffetype_new ();
11416 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11418 ffetype_set_ams (type,
11419 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11420 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11421 ffetype_set_star (base_type,
11422 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11424 ffetype_set_kind (base_type, 1, type);
11425 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
11427 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11428 = t = make_signed_type (CHAR_TYPE_SIZE);
11429 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11431 type = ffetype_new ();
11432 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11434 ffetype_set_ams (type,
11435 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11436 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11437 ffetype_set_star (base_type,
11438 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11440 ffetype_set_kind (base_type, 3, type);
11441 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
11443 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11444 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11445 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11447 type = ffetype_new ();
11448 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11450 ffetype_set_ams (type,
11451 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11452 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11453 ffetype_set_star (base_type,
11454 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11456 ffetype_set_kind (base_type, 6, type);
11457 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
11459 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11460 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11461 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11463 type = ffetype_new ();
11464 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11466 ffetype_set_ams (type,
11467 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11468 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11469 ffetype_set_star (base_type,
11470 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11472 ffetype_set_kind (base_type, 2, type);
11473 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
11475 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11476 = t = make_node (REAL_TYPE);
11477 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11478 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11481 type = ffetype_new ();
11483 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11485 ffetype_set_ams (type,
11486 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11487 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11488 ffetype_set_star (base_type,
11489 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11491 ffetype_set_kind (base_type, 1, type);
11492 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11493 = FFETARGET_f2cTYREAL;
11494 assert (ffetype_size (type) == sizeof (ffetargetReal1));
11496 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11497 = t = make_node (REAL_TYPE);
11498 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11499 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11502 type = ffetype_new ();
11503 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11505 ffetype_set_ams (type,
11506 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11507 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11508 ffetype_set_star (base_type,
11509 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11511 ffetype_set_kind (base_type, 2, type);
11512 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11513 = FFETARGET_f2cTYDREAL;
11514 assert (ffetype_size (type) == sizeof (ffetargetReal2));
11516 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11517 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11518 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11520 type = ffetype_new ();
11522 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11524 ffetype_set_ams (type,
11525 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11526 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11527 ffetype_set_star (base_type,
11528 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11530 ffetype_set_kind (base_type, 1, type);
11531 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11532 = FFETARGET_f2cTYCOMPLEX;
11533 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
11535 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11536 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11537 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11539 type = ffetype_new ();
11540 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11542 ffetype_set_ams (type,
11543 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11544 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11545 ffetype_set_star (base_type,
11546 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11548 ffetype_set_kind (base_type, 2,
11550 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11551 = FFETARGET_f2cTYDCOMPLEX;
11552 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
11554 /* Make function and ptr-to-function types for non-CHARACTER types. */
11556 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11557 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11559 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11561 if (i == FFEINFO_basictypeINTEGER)
11563 /* Figure out the smallest INTEGER type that can hold
11564 a pointer on this machine. */
11565 if (GET_MODE_SIZE (TYPE_MODE (t))
11566 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11568 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11569 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11570 > GET_MODE_SIZE (TYPE_MODE (t))))
11571 ffecom_pointer_kind_ = j;
11574 else if (i == FFEINFO_basictypeCOMPLEX)
11575 t = void_type_node;
11576 /* For f2c compatibility, REAL functions are really
11577 implemented as DOUBLE PRECISION. */
11578 else if ((i == FFEINFO_basictypeREAL)
11579 && (j == FFEINFO_kindtypeREAL1))
11580 t = ffecom_tree_type
11581 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
11583 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11585 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11589 /* Set up pointer types. */
11591 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
11592 fatal_error ("no INTEGER type can hold a pointer on this configuration");
11593 else if (0 && ffe_is_do_internal_checks ())
11594 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11595 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11596 FFEINFO_kindtypeINTEGERDEFAULT),
11598 ffeinfo_type (FFEINFO_basictypeINTEGER,
11599 ffecom_pointer_kind_));
11601 if (ffe_is_ugly_assign ())
11602 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
11604 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11605 if (0 && ffe_is_do_internal_checks ())
11606 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
11608 ffecom_integer_type_node
11609 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11610 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11611 integer_zero_node);
11612 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11615 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11616 Turns out that by TYLONG, runtime/libI77/lio.h really means
11617 "whatever size an ftnint is". For consistency and sanity,
11618 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
11619 all are INTEGER, which we also make out of whatever back-end
11620 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
11621 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
11622 accommodate machines like the Alpha. Note that this suggests
11623 f2c and libf2c are missing a distinction perhaps needed on
11624 some machines between "int" and "long int". -- burley 0.5.5 950215 */
11626 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
11627 FFETARGET_f2cTYLONG);
11628 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
11629 FFETARGET_f2cTYSHORT);
11630 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
11631 FFETARGET_f2cTYINT1);
11632 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
11633 FFETARGET_f2cTYQUAD);
11634 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
11635 FFETARGET_f2cTYLOGICAL);
11636 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
11637 FFETARGET_f2cTYLOGICAL2);
11638 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
11639 FFETARGET_f2cTYLOGICAL1);
11640 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
11641 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
11642 FFETARGET_f2cTYQUAD);
11644 /* CHARACTER stuff is all special-cased, so it is not handled in the above
11645 loop. CHARACTER items are built as arrays of unsigned char. */
11647 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
11648 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
11649 type = ffetype_new ();
11651 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
11652 FFEINFO_kindtypeCHARACTER1,
11654 ffetype_set_ams (type,
11655 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11656 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11657 ffetype_set_kind (base_type, 1, type);
11658 assert (ffetype_size (type)
11659 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
11661 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
11662 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
11663 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
11664 [FFEINFO_kindtypeCHARACTER1]
11665 = ffecom_tree_ptr_to_fun_type_void;
11666 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
11667 = FFETARGET_f2cTYCHAR;
11669 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
11672 /* Make multi-return-value type and fields. */
11674 ffecom_multi_type_node_ = make_node (UNION_TYPE);
11678 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11679 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11683 if (ffecom_tree_type[i][j] == NULL_TREE)
11684 continue; /* Not supported. */
11685 sprintf (&name[0], "bt_%s_kt_%s",
11686 ffeinfo_basictype_string ((ffeinfoBasictype) i),
11687 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
11688 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
11689 get_identifier (name),
11690 ffecom_tree_type[i][j]);
11691 DECL_CONTEXT (ffecom_multi_fields_[i][j])
11692 = ffecom_multi_type_node_;
11693 DECL_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11694 DECL_USER_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11695 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
11696 field = ffecom_multi_fields_[i][j];
11699 TYPE_FIELDS (ffecom_multi_type_node_) = field;
11700 layout_type (ffecom_multi_type_node_);
11702 /* Subroutines usually return integer because they might have alternate
11705 ffecom_tree_subr_type
11706 = build_function_type (integer_type_node, NULL_TREE);
11707 ffecom_tree_ptr_to_subr_type
11708 = build_pointer_type (ffecom_tree_subr_type);
11709 ffecom_tree_blockdata_type
11710 = build_function_type (void_type_node, NULL_TREE);
11712 builtin_function ("__builtin_sqrtf", float_ftype_float,
11713 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtf");
11714 builtin_function ("__builtin_fsqrt", double_ftype_double,
11715 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrt");
11716 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
11717 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtl");
11718 builtin_function ("__builtin_sinf", float_ftype_float,
11719 BUILT_IN_SIN, BUILT_IN_NORMAL, "sinf");
11720 builtin_function ("__builtin_sin", double_ftype_double,
11721 BUILT_IN_SIN, BUILT_IN_NORMAL, "sin");
11722 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
11723 BUILT_IN_SIN, BUILT_IN_NORMAL, "sinl");
11724 builtin_function ("__builtin_cosf", float_ftype_float,
11725 BUILT_IN_COS, BUILT_IN_NORMAL, "cosf");
11726 builtin_function ("__builtin_cos", double_ftype_double,
11727 BUILT_IN_COS, BUILT_IN_NORMAL, "cos");
11728 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
11729 BUILT_IN_COS, BUILT_IN_NORMAL, "cosl");
11731 pedantic_lvalues = FALSE;
11733 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
11736 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
11739 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
11742 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
11743 FFECOM_f2cDOUBLEREAL,
11745 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
11748 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
11749 FFECOM_f2cDOUBLECOMPLEX,
11751 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
11754 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
11757 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
11760 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
11763 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
11767 ffecom_f2c_ftnlen_zero_node
11768 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
11770 ffecom_f2c_ftnlen_one_node
11771 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
11773 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
11774 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
11776 ffecom_f2c_ptr_to_ftnlen_type_node
11777 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
11779 ffecom_f2c_ptr_to_ftnint_type_node
11780 = build_pointer_type (ffecom_f2c_ftnint_type_node);
11782 ffecom_f2c_ptr_to_integer_type_node
11783 = build_pointer_type (ffecom_f2c_integer_type_node);
11785 ffecom_f2c_ptr_to_real_type_node
11786 = build_pointer_type (ffecom_f2c_real_type_node);
11788 ffecom_float_zero_ = build_real (float_type_node, dconst0);
11789 ffecom_double_zero_ = build_real (double_type_node, dconst0);
11791 REAL_VALUE_TYPE point_5;
11793 #ifdef REAL_ARITHMETIC
11794 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
11798 ffecom_float_half_ = build_real (float_type_node, point_5);
11799 ffecom_double_half_ = build_real (double_type_node, point_5);
11802 /* Do "extern int xargc;". */
11804 ffecom_tree_xargc_ = build_decl (VAR_DECL,
11805 get_identifier ("f__xargc"),
11806 integer_type_node);
11807 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
11808 TREE_STATIC (ffecom_tree_xargc_) = 1;
11809 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
11810 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
11811 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
11813 #if 0 /* This is being fixed, and seems to be working now. */
11814 if ((FLOAT_TYPE_SIZE != 32)
11815 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
11817 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
11818 (int) FLOAT_TYPE_SIZE);
11819 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
11820 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
11821 warning ("properly unless they all are 32 bits wide.");
11822 warning ("Please keep this in mind before you report bugs. g77 should");
11823 warning ("support non-32-bit machines better as of version 0.6.");
11827 #if 0 /* Code in ste.c that would crash has been commented out. */
11828 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
11829 < TYPE_PRECISION (string_type_node))
11830 /* I/O will probably crash. */
11831 warning ("configuration: char * holds %d bits, but ftnlen only %d",
11832 TYPE_PRECISION (string_type_node),
11833 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
11836 #if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
11837 if (TYPE_PRECISION (ffecom_integer_type_node)
11838 < TYPE_PRECISION (string_type_node))
11839 /* ASSIGN 10 TO I will crash. */
11840 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
11841 ASSIGN statement might fail",
11842 TYPE_PRECISION (string_type_node),
11843 TYPE_PRECISION (ffecom_integer_type_node));
11847 /* ffecom_init_2 -- Initialize
11849 ffecom_init_2(); */
11854 assert (ffecom_outer_function_decl_ == NULL_TREE);
11855 assert (current_function_decl == NULL_TREE);
11856 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
11858 ffecom_master_arglist_ = NULL;
11860 ffecom_primary_entry_ = NULL;
11861 ffecom_is_altreturning_ = FALSE;
11862 ffecom_func_result_ = NULL_TREE;
11863 ffecom_multi_retval_ = NULL_TREE;
11866 /* ffecom_list_expr -- Transform list of exprs into gcc tree
11869 ffebld expr; // FFE opITEM list.
11870 tree = ffecom_list_expr(expr);
11872 List of actual args is transformed into corresponding gcc backend list. */
11875 ffecom_list_expr (ffebld expr)
11878 tree *plist = &list;
11879 tree trail = NULL_TREE; /* Append char length args here. */
11880 tree *ptrail = &trail;
11883 while (expr != NULL)
11885 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
11887 if (texpr == error_mark_node)
11888 return error_mark_node;
11890 *plist = build_tree_list (NULL_TREE, texpr);
11891 plist = &TREE_CHAIN (*plist);
11892 expr = ffebld_trail (expr);
11893 if (length != NULL_TREE)
11895 *ptrail = build_tree_list (NULL_TREE, length);
11896 ptrail = &TREE_CHAIN (*ptrail);
11905 /* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
11908 ffebld expr; // FFE opITEM list.
11909 tree = ffecom_list_ptr_to_expr(expr);
11911 List of actual args is transformed into corresponding gcc backend list for
11912 use in calling an external procedure (vs. a statement function). */
11915 ffecom_list_ptr_to_expr (ffebld expr)
11918 tree *plist = &list;
11919 tree trail = NULL_TREE; /* Append char length args here. */
11920 tree *ptrail = &trail;
11923 while (expr != NULL)
11925 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
11927 if (texpr == error_mark_node)
11928 return error_mark_node;
11930 *plist = build_tree_list (NULL_TREE, texpr);
11931 plist = &TREE_CHAIN (*plist);
11932 expr = ffebld_trail (expr);
11933 if (length != NULL_TREE)
11935 *ptrail = build_tree_list (NULL_TREE, length);
11936 ptrail = &TREE_CHAIN (*ptrail);
11945 /* Obtain gcc's LABEL_DECL tree for label. */
11948 ffecom_lookup_label (ffelab label)
11952 if (ffelab_hook (label) == NULL_TREE)
11954 char labelname[16];
11956 switch (ffelab_type (label))
11958 case FFELAB_typeLOOPEND:
11959 case FFELAB_typeNOTLOOP:
11960 case FFELAB_typeENDIF:
11961 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
11962 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
11964 DECL_CONTEXT (glabel) = current_function_decl;
11965 DECL_MODE (glabel) = VOIDmode;
11968 case FFELAB_typeFORMAT:
11969 glabel = build_decl (VAR_DECL,
11970 ffecom_get_invented_identifier
11971 ("__g77_format_%d", (int) ffelab_value (label)),
11972 build_type_variant (build_array_type
11976 TREE_CONSTANT (glabel) = 1;
11977 TREE_STATIC (glabel) = 1;
11978 DECL_CONTEXT (glabel) = current_function_decl;
11979 DECL_INITIAL (glabel) = NULL;
11980 make_decl_rtl (glabel, NULL);
11981 expand_decl (glabel);
11983 ffecom_save_tree_forever (glabel);
11987 case FFELAB_typeANY:
11988 glabel = error_mark_node;
11992 assert ("bad label type" == NULL);
11996 ffelab_set_hook (label, glabel);
12000 glabel = ffelab_hook (label);
12006 /* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12007 a single source specification (as in the fourth argument of MVBITS).
12008 If the type is NULL_TREE, the type of lhs is used to make the type of
12009 the MODIFY_EXPR. */
12012 ffecom_modify (tree newtype, tree lhs,
12015 if (lhs == error_mark_node || rhs == error_mark_node)
12016 return error_mark_node;
12018 if (newtype == NULL_TREE)
12019 newtype = TREE_TYPE (lhs);
12021 if (TREE_SIDE_EFFECTS (lhs))
12022 lhs = stabilize_reference (lhs);
12024 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12027 /* Register source file name. */
12030 ffecom_file (const char *name)
12032 ffecom_file_ (name);
12035 /* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
12038 ffecom_notify_init_storage(st);
12040 Gets called when all possible units in an aggregate storage area (a LOCAL
12041 with equivalences or a COMMON) have been initialized. The initialization
12042 info either is in ffestorag_init or, if that is NULL,
12043 ffestorag_accretion:
12045 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12046 even for an array if the array is one element in length!
12048 ffestorag_accretion will contain an opACCTER. It is much like an
12049 opARRTER except it has an ffebit object in it instead of just a size.
12050 The back end can use the info in the ffebit object, if it wants, to
12051 reduce the amount of actual initialization, but in any case it should
12052 kill the ffebit object when done. Also, set accretion to NULL but
12053 init to a non-NULL value.
12055 After performing initialization, DO NOT set init to NULL, because that'll
12056 tell the front end it is ok for more initialization to happen. Instead,
12057 set init to an opANY expression or some such thing that you can use to
12058 tell that you've already initialized the object.
12061 Support two-pass FFE. */
12064 ffecom_notify_init_storage (ffestorag st)
12066 ffebld init; /* The initialization expression. */
12068 if (ffestorag_init (st) == NULL)
12070 init = ffestorag_accretion (st);
12071 assert (init != NULL);
12072 ffestorag_set_accretion (st, NULL);
12073 ffestorag_set_accretes (st, 0);
12074 ffestorag_set_init (st, init);
12078 /* ffecom_notify_init_symbol -- A symbol is now fully init'ed
12081 ffecom_notify_init_symbol(s);
12083 Gets called when all possible units in a symbol (not placed in COMMON
12084 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12085 have been initialized. The initialization info either is in
12086 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
12088 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12089 even for an array if the array is one element in length!
12091 ffesymbol_accretion will contain an opACCTER. It is much like an
12092 opARRTER except it has an ffebit object in it instead of just a size.
12093 The back end can use the info in the ffebit object, if it wants, to
12094 reduce the amount of actual initialization, but in any case it should
12095 kill the ffebit object when done. Also, set accretion to NULL but
12096 init to a non-NULL value.
12098 After performing initialization, DO NOT set init to NULL, because that'll
12099 tell the front end it is ok for more initialization to happen. Instead,
12100 set init to an opANY expression or some such thing that you can use to
12101 tell that you've already initialized the object.
12104 Support two-pass FFE. */
12107 ffecom_notify_init_symbol (ffesymbol s)
12109 ffebld init; /* The initialization expression. */
12111 if (ffesymbol_storage (s) == NULL)
12112 return; /* Do nothing until COMMON/EQUIVALENCE
12113 possibilities checked. */
12115 if ((ffesymbol_init (s) == NULL)
12116 && ((init = ffesymbol_accretion (s)) != NULL))
12118 ffesymbol_set_accretion (s, NULL);
12119 ffesymbol_set_accretes (s, 0);
12120 ffesymbol_set_init (s, init);
12124 /* ffecom_notify_primary_entry -- Learn which is the primary entry point
12127 ffecom_notify_primary_entry(s);
12129 Gets called when implicit or explicit PROGRAM statement seen or when
12130 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12131 global symbol that serves as the entry point. */
12134 ffecom_notify_primary_entry (ffesymbol s)
12136 ffecom_primary_entry_ = s;
12137 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
12139 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12140 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12141 ffecom_primary_entry_is_proc_ = TRUE;
12143 ffecom_primary_entry_is_proc_ = FALSE;
12145 if (!ffe_is_silent ())
12147 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12148 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12150 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12153 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12158 for (list = ffesymbol_dummyargs (s);
12160 list = ffebld_trail (list))
12162 arg = ffebld_head (list);
12163 if (ffebld_op (arg) == FFEBLD_opSTAR)
12165 ffecom_is_altreturning_ = TRUE;
12173 ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12175 return ffecom_open_include_ (name, l, c);
12178 /* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
12181 ffebld expr; // FFE expression.
12182 tree = ffecom_ptr_to_expr(expr);
12184 Like ffecom_expr, but sticks address-of in front of most things. */
12187 ffecom_ptr_to_expr (ffebld expr)
12190 ffeinfoBasictype bt;
12191 ffeinfoKindtype kt;
12194 assert (expr != NULL);
12196 switch (ffebld_op (expr))
12198 case FFEBLD_opSYMTER:
12199 s = ffebld_symter (expr);
12200 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12204 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12205 assert (ix != FFECOM_gfrt);
12206 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12208 ffecom_make_gfrt_ (ix);
12209 item = ffecom_gfrt_[ix];
12214 item = ffesymbol_hook (s).decl_tree;
12215 if (item == NULL_TREE)
12217 s = ffecom_sym_transform_ (s);
12218 item = ffesymbol_hook (s).decl_tree;
12221 assert (item != NULL);
12222 if (item == error_mark_node)
12224 if (!ffesymbol_hook (s).addr)
12225 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12229 case FFEBLD_opARRAYREF:
12230 return ffecom_arrayref_ (NULL_TREE, expr, 1);
12232 case FFEBLD_opCONTER:
12234 bt = ffeinfo_basictype (ffebld_info (expr));
12235 kt = ffeinfo_kindtype (ffebld_info (expr));
12237 item = ffecom_constantunion (&ffebld_constant_union
12238 (ffebld_conter (expr)), bt, kt,
12239 ffecom_tree_type[bt][kt]);
12240 if (item == error_mark_node)
12241 return error_mark_node;
12242 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12247 return error_mark_node;
12250 bt = ffeinfo_basictype (ffebld_info (expr));
12251 kt = ffeinfo_kindtype (ffebld_info (expr));
12253 item = ffecom_expr (expr);
12254 if (item == error_mark_node)
12255 return error_mark_node;
12257 /* The back end currently optimizes a bit too zealously for us, in that
12258 we fail JCB001 if the following block of code is omitted. It checks
12259 to see if the transformed expression is a symbol or array reference,
12260 and encloses it in a SAVE_EXPR if that is the case. */
12263 if ((TREE_CODE (item) == VAR_DECL)
12264 || (TREE_CODE (item) == PARM_DECL)
12265 || (TREE_CODE (item) == RESULT_DECL)
12266 || (TREE_CODE (item) == INDIRECT_REF)
12267 || (TREE_CODE (item) == ARRAY_REF)
12268 || (TREE_CODE (item) == COMPONENT_REF)
12270 || (TREE_CODE (item) == OFFSET_REF)
12272 || (TREE_CODE (item) == BUFFER_REF)
12273 || (TREE_CODE (item) == REALPART_EXPR)
12274 || (TREE_CODE (item) == IMAGPART_EXPR))
12276 item = ffecom_save_tree (item);
12279 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12284 assert ("fall-through error" == NULL);
12285 return error_mark_node;
12288 /* Obtain a temp var with given data type.
12290 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12291 or >= 0 for a CHARACTER type.
12293 elements is -1 for a scalar or > 0 for an array of type. */
12296 ffecom_make_tempvar (const char *commentary, tree type,
12297 ffetargetCharacterSize size, int elements)
12300 static int mynumber;
12302 assert (current_binding_level->prep_state < 2);
12304 if (type == error_mark_node)
12305 return error_mark_node;
12307 if (size != FFETARGET_charactersizeNONE)
12308 type = build_array_type (type,
12309 build_range_type (ffecom_f2c_ftnlen_type_node,
12310 ffecom_f2c_ftnlen_one_node,
12311 build_int_2 (size, 0)));
12312 if (elements != -1)
12313 type = build_array_type (type,
12314 build_range_type (integer_type_node,
12316 build_int_2 (elements - 1,
12318 t = build_decl (VAR_DECL,
12319 ffecom_get_invented_identifier ("__g77_%s_%d",
12324 t = start_decl (t, FALSE);
12325 finish_decl (t, NULL_TREE, FALSE);
12330 /* Prepare argument pointer to expression.
12332 Like ffecom_prepare_expr, except for expressions to be evaluated
12333 via ffecom_arg_ptr_to_expr. */
12336 ffecom_prepare_arg_ptr_to_expr (ffebld expr)
12338 /* ~~For now, it seems to be the same thing. */
12339 ffecom_prepare_expr (expr);
12343 /* End of preparations. */
12346 ffecom_prepare_end (void)
12348 int prep_state = current_binding_level->prep_state;
12350 assert (prep_state < 2);
12351 current_binding_level->prep_state = 2;
12353 return (prep_state == 1) ? TRUE : FALSE;
12356 /* Prepare expression.
12358 This is called before any code is generated for the current block.
12359 It scans the expression, declares any temporaries that might be needed
12360 during evaluation of the expression, and stores those temporaries in
12361 the appropriate "hook" fields of the expression. `dest', if not NULL,
12362 specifies the destination that ffecom_expr_ will see, in case that
12363 helps avoid generating unused temporaries.
12365 ~~Improve to avoid allocating unused temporaries by taking `dest'
12366 into account vis-a-vis aliasing requirements of complex/character
12370 ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
12372 ffeinfoBasictype bt;
12373 ffeinfoKindtype kt;
12374 ffetargetCharacterSize sz;
12375 tree tempvar = NULL_TREE;
12377 assert (current_binding_level->prep_state < 2);
12382 bt = ffeinfo_basictype (ffebld_info (expr));
12383 kt = ffeinfo_kindtype (ffebld_info (expr));
12384 sz = ffeinfo_size (ffebld_info (expr));
12386 /* Generate whatever temporaries are needed to represent the result
12387 of the expression. */
12389 if (bt == FFEINFO_basictypeCHARACTER)
12391 while (ffebld_op (expr) == FFEBLD_opPAREN)
12392 expr = ffebld_left (expr);
12395 switch (ffebld_op (expr))
12398 /* Don't make temps for SYMTER, CONTER, etc. */
12399 if (ffebld_arity (expr) == 0)
12404 case FFEINFO_basictypeCOMPLEX:
12405 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12409 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12412 s = ffebld_symter (ffebld_left (expr));
12413 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
12414 || (ffesymbol_where (s) != FFEINFO_whereINTRINSIC
12415 && ! ffesymbol_is_f2c (s))
12416 || (ffesymbol_where (s) == FFEINFO_whereINTRINSIC
12417 && ! ffe_is_f2c_library ()))
12420 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12422 /* Requires special treatment. There's no POW_CC function
12423 in libg2c, so POW_ZZ is used, which means we always
12424 need a double-complex temp, not a single-complex. */
12425 kt = FFEINFO_kindtypeREAL2;
12427 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12428 /* The other ops don't need temps for complex operands. */
12431 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12432 REAL(C). See 19990325-0.f, routine `check', for cases. */
12433 tempvar = ffecom_make_tempvar ("complex",
12435 [FFEINFO_basictypeCOMPLEX][kt],
12436 FFETARGET_charactersizeNONE,
12440 case FFEINFO_basictypeCHARACTER:
12441 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12444 if (sz == FFETARGET_charactersizeNONE)
12445 /* ~~Kludge alert! This should someday be fixed. */
12448 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
12457 case FFEBLD_opPOWER:
12460 tree rtmp, ltmp, result;
12462 ltype = ffecom_type_expr (ffebld_left (expr));
12463 rtype = ffecom_type_expr (ffebld_right (expr));
12465 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
12466 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12467 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12469 tempvar = make_tree_vec (3);
12470 TREE_VEC_ELT (tempvar, 0) = rtmp;
12471 TREE_VEC_ELT (tempvar, 1) = ltmp;
12472 TREE_VEC_ELT (tempvar, 2) = result;
12477 case FFEBLD_opCONCATENATE:
12479 /* This gets special handling, because only one set of temps
12480 is needed for a tree of these -- the tree is treated as
12481 a flattened list of concatenations when generating code. */
12483 ffecomConcatList_ catlist;
12484 tree ltmp, itmp, result;
12488 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12489 count = ffecom_concat_list_count_ (catlist);
12494 = ffecom_make_tempvar ("concat_len",
12495 ffecom_f2c_ftnlen_type_node,
12496 FFETARGET_charactersizeNONE, count);
12498 = ffecom_make_tempvar ("concat_item",
12499 ffecom_f2c_address_type_node,
12500 FFETARGET_charactersizeNONE, count);
12502 = ffecom_make_tempvar ("concat_res",
12504 ffecom_concat_list_maxlen_ (catlist),
12507 tempvar = make_tree_vec (3);
12508 TREE_VEC_ELT (tempvar, 0) = ltmp;
12509 TREE_VEC_ELT (tempvar, 1) = itmp;
12510 TREE_VEC_ELT (tempvar, 2) = result;
12513 for (i = 0; i < count; ++i)
12514 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
12517 ffecom_concat_list_kill_ (catlist);
12521 ffebld_nonter_set_hook (expr, tempvar);
12522 current_binding_level->prep_state = 1;
12527 case FFEBLD_opCONVERT:
12528 if (bt == FFEINFO_basictypeCHARACTER
12529 && ((ffebld_size_known (ffebld_left (expr))
12530 == FFETARGET_charactersizeNONE)
12531 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
12532 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
12538 ffebld_nonter_set_hook (expr, tempvar);
12539 current_binding_level->prep_state = 1;
12542 /* Prepare subexpressions for this expr. */
12544 switch (ffebld_op (expr))
12546 case FFEBLD_opPERCENT_LOC:
12547 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
12550 case FFEBLD_opPERCENT_VAL:
12551 case FFEBLD_opPERCENT_REF:
12552 ffecom_prepare_expr (ffebld_left (expr));
12555 case FFEBLD_opPERCENT_DESCR:
12556 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
12559 case FFEBLD_opITEM:
12565 item = ffebld_trail (item))
12566 if (ffebld_head (item) != NULL)
12567 ffecom_prepare_expr (ffebld_head (item));
12572 /* Need to handle character conversion specially. */
12573 switch (ffebld_arity (expr))
12576 ffecom_prepare_expr (ffebld_left (expr));
12577 ffecom_prepare_expr (ffebld_right (expr));
12581 ffecom_prepare_expr (ffebld_left (expr));
12592 /* Prepare expression for reading and writing.
12594 Like ffecom_prepare_expr, except for expressions to be evaluated
12595 via ffecom_expr_rw. */
12598 ffecom_prepare_expr_rw (tree type, ffebld expr)
12600 /* This is all we support for now. */
12601 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
12603 /* ~~For now, it seems to be the same thing. */
12604 ffecom_prepare_expr (expr);
12608 /* Prepare expression for writing.
12610 Like ffecom_prepare_expr, except for expressions to be evaluated
12611 via ffecom_expr_w. */
12614 ffecom_prepare_expr_w (tree type, ffebld expr)
12616 /* This is all we support for now. */
12617 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
12619 /* ~~For now, it seems to be the same thing. */
12620 ffecom_prepare_expr (expr);
12624 /* Prepare expression for returning.
12626 Like ffecom_prepare_expr, except for expressions to be evaluated
12627 via ffecom_return_expr. */
12630 ffecom_prepare_return_expr (ffebld expr)
12632 assert (current_binding_level->prep_state < 2);
12634 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
12635 && ffecom_is_altreturning_
12637 ffecom_prepare_expr (expr);
12640 /* Prepare pointer to expression.
12642 Like ffecom_prepare_expr, except for expressions to be evaluated
12643 via ffecom_ptr_to_expr. */
12646 ffecom_prepare_ptr_to_expr (ffebld expr)
12648 /* ~~For now, it seems to be the same thing. */
12649 ffecom_prepare_expr (expr);
12653 /* Transform expression into constant pointer-to-expression tree.
12655 If the expression can be transformed into a pointer-to-expression tree
12656 that is constant, that is done, and the tree returned. Else NULL_TREE
12659 That way, a caller can attempt to provide compile-time initialization
12660 of a variable and, if that fails, *then* choose to start a new block
12661 and resort to using temporaries, as appropriate. */
12664 ffecom_ptr_to_const_expr (ffebld expr)
12667 return integer_zero_node;
12669 if (ffebld_op (expr) == FFEBLD_opANY)
12670 return error_mark_node;
12672 if (ffebld_arity (expr) == 0
12673 && (ffebld_op (expr) != FFEBLD_opSYMTER
12674 || ffebld_where (expr) == FFEINFO_whereCOMMON
12675 || ffebld_where (expr) == FFEINFO_whereGLOBAL
12676 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
12680 t = ffecom_ptr_to_expr (expr);
12681 assert (TREE_CONSTANT (t));
12688 /* ffecom_return_expr -- Returns return-value expr given alt return expr
12690 tree rtn; // NULL_TREE means use expand_null_return()
12691 ffebld expr; // NULL if no alt return expr to RETURN stmt
12692 rtn = ffecom_return_expr(expr);
12694 Based on the program unit type and other info (like return function
12695 type, return master function type when alternate ENTRY points,
12696 whether subroutine has any alternate RETURN points, etc), returns the
12697 appropriate expression to be returned to the caller, or NULL_TREE
12698 meaning no return value or the caller expects it to be returned somewhere
12699 else (which is handled by other parts of this module). */
12702 ffecom_return_expr (ffebld expr)
12706 switch (ffecom_primary_entry_kind_)
12708 case FFEINFO_kindPROGRAM:
12709 case FFEINFO_kindBLOCKDATA:
12713 case FFEINFO_kindSUBROUTINE:
12714 if (!ffecom_is_altreturning_)
12715 rtn = NULL_TREE; /* No alt returns, never an expr. */
12716 else if (expr == NULL)
12717 rtn = integer_zero_node;
12719 rtn = ffecom_expr (expr);
12722 case FFEINFO_kindFUNCTION:
12723 if ((ffecom_multi_retval_ != NULL_TREE)
12724 || (ffesymbol_basictype (ffecom_primary_entry_)
12725 == FFEINFO_basictypeCHARACTER)
12726 || ((ffesymbol_basictype (ffecom_primary_entry_)
12727 == FFEINFO_basictypeCOMPLEX)
12728 && (ffecom_num_entrypoints_ == 0)
12729 && ffesymbol_is_f2c (ffecom_primary_entry_)))
12730 { /* Value is returned by direct assignment
12731 into (implicit) dummy. */
12735 rtn = ffecom_func_result_;
12737 /* Spurious error if RETURN happens before first reference! So elide
12738 this code. In particular, for debugging registry, rtn should always
12739 be non-null after all, but TREE_USED won't be set until we encounter
12740 a reference in the code. Perfectly okay (but weird) code that,
12741 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
12742 this diagnostic for no reason. Have people use -O -Wuninitialized
12743 and leave it to the back end to find obviously weird cases. */
12745 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
12746 situation; if the return value has never been referenced, it won't
12747 have a tree under 2pass mode. */
12748 if ((rtn == NULL_TREE)
12749 || !TREE_USED (rtn))
12751 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
12752 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
12753 ffesymbol_where_column (ffecom_primary_entry_));
12754 ffebad_string (ffesymbol_text (ffesymbol_funcresult
12755 (ffecom_primary_entry_)));
12762 assert ("bad unit kind" == NULL);
12763 case FFEINFO_kindANY:
12764 rtn = error_mark_node;
12771 /* Do save_expr only if tree is not error_mark_node. */
12774 ffecom_save_tree (tree t)
12776 return save_expr (t);
12779 /* Start a compound statement (block). */
12782 ffecom_start_compstmt (void)
12784 bison_rule_pushlevel_ ();
12787 /* Public entry point for front end to access start_decl. */
12790 ffecom_start_decl (tree decl, bool is_initialized)
12792 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
12793 return start_decl (decl, FALSE);
12796 /* ffecom_sym_commit -- Symbol's state being committed to reality
12799 ffecom_sym_commit(s);
12801 Does whatever the backend needs when a symbol is committed after having
12802 been backtrackable for a period of time. */
12805 ffecom_sym_commit (ffesymbol s UNUSED)
12807 assert (!ffesymbol_retractable ());
12810 /* ffecom_sym_end_transition -- Perform end transition on all symbols
12812 ffecom_sym_end_transition();
12814 Does backend-specific stuff and also calls ffest_sym_end_transition
12815 to do the necessary FFE stuff.
12817 Backtracking is never enabled when this fn is called, so don't worry
12821 ffecom_sym_end_transition (ffesymbol s)
12825 assert (!ffesymbol_retractable ());
12827 s = ffest_sym_end_transition (s);
12829 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
12830 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
12832 ffecom_list_blockdata_
12833 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12834 FFEINTRIN_specNONE,
12835 FFEINTRIN_impNONE),
12836 ffecom_list_blockdata_);
12839 /* This is where we finally notice that a symbol has partial initialization
12840 and finalize it. */
12842 if (ffesymbol_accretion (s) != NULL)
12844 assert (ffesymbol_init (s) == NULL);
12845 ffecom_notify_init_symbol (s);
12847 else if (((st = ffesymbol_storage (s)) != NULL)
12848 && ((st = ffestorag_parent (st)) != NULL)
12849 && (ffestorag_accretion (st) != NULL))
12851 assert (ffestorag_init (st) == NULL);
12852 ffecom_notify_init_storage (st);
12855 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
12856 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
12857 && (ffesymbol_storage (s) != NULL))
12859 ffecom_list_common_
12860 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12861 FFEINTRIN_specNONE,
12862 FFEINTRIN_impNONE),
12863 ffecom_list_common_);
12869 /* ffecom_sym_exec_transition -- Perform exec transition on all symbols
12871 ffecom_sym_exec_transition();
12873 Does backend-specific stuff and also calls ffest_sym_exec_transition
12874 to do the necessary FFE stuff.
12876 See the long-winded description in ffecom_sym_learned for info
12877 on handling the situation where backtracking is inhibited. */
12880 ffecom_sym_exec_transition (ffesymbol s)
12882 s = ffest_sym_exec_transition (s);
12887 /* ffecom_sym_learned -- Initial or more info gained on symbol after exec
12890 s = ffecom_sym_learned(s);
12892 Called when a new symbol is seen after the exec transition or when more
12893 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
12894 it arrives here is that all its latest info is updated already, so its
12895 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
12896 field filled in if its gone through here or exec_transition first, and
12899 The backend probably wants to check ffesymbol_retractable() to see if
12900 backtracking is in effect. If so, the FFE's changes to the symbol may
12901 be retracted (undone) or committed (ratified), at which time the
12902 appropriate ffecom_sym_retract or _commit function will be called
12905 If the backend has its own backtracking mechanism, great, use it so that
12906 committal is a simple operation. Though it doesn't make much difference,
12907 I suppose: the reason for tentative symbol evolution in the FFE is to
12908 enable error detection in weird incorrect statements early and to disable
12909 incorrect error detection on a correct statement. The backend is not
12910 likely to introduce any information that'll get involved in these
12911 considerations, so it is probably just fine that the implementation
12912 model for this fn and for _exec_transition is to not do anything
12913 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
12914 and instead wait until ffecom_sym_commit is called (which it never
12915 will be as long as we're using ambiguity-detecting statement analysis in
12916 the FFE, which we are initially to shake out the code, but don't depend
12917 on this), otherwise go ahead and do whatever is needed.
12919 In essence, then, when this fn and _exec_transition get called while
12920 backtracking is enabled, a general mechanism would be to flag which (or
12921 both) of these were called (and in what order? neat question as to what
12922 might happen that I'm too lame to think through right now) and then when
12923 _commit is called reproduce the original calling sequence, if any, for
12924 the two fns (at which point backtracking will, of course, be disabled). */
12927 ffecom_sym_learned (ffesymbol s)
12929 ffestorag_exec_layout (s);
12934 /* ffecom_sym_retract -- Symbol's state being retracted from reality
12937 ffecom_sym_retract(s);
12939 Does whatever the backend needs when a symbol is retracted after having
12940 been backtrackable for a period of time. */
12943 ffecom_sym_retract (ffesymbol s UNUSED)
12945 assert (!ffesymbol_retractable ());
12947 #if 0 /* GCC doesn't commit any backtrackable sins,
12948 so nothing needed here. */
12949 switch (ffesymbol_hook (s).state)
12951 case 0: /* nothing happened yet. */
12954 case 1: /* exec transition happened. */
12957 case 2: /* learned happened. */
12960 case 3: /* learned then exec. */
12963 case 4: /* exec then learned. */
12967 assert ("bad hook state" == NULL);
12973 /* Create temporary gcc label. */
12976 ffecom_temp_label ()
12979 static int mynumber = 0;
12981 glabel = build_decl (LABEL_DECL,
12982 ffecom_get_invented_identifier ("__g77_label_%d",
12985 DECL_CONTEXT (glabel) = current_function_decl;
12986 DECL_MODE (glabel) = VOIDmode;
12991 /* Return an expression that is usable as an arg in a conditional context
12992 (IF, DO WHILE, .NOT., and so on).
12994 Use the one provided for the back end as of >2.6.0. */
12997 ffecom_truth_value (tree expr)
12999 return truthvalue_conversion (expr);
13002 /* Return the inversion of a truth value (the inversion of what
13003 ffecom_truth_value builds).
13005 Apparently invert_truthvalue, which is properly in the back end, is
13006 enough for now, so just use it. */
13009 ffecom_truth_value_invert (tree expr)
13011 return invert_truthvalue (ffecom_truth_value (expr));
13014 /* Return the tree that is the type of the expression, as would be
13015 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13016 transforming the expression, generating temporaries, etc. */
13019 ffecom_type_expr (ffebld expr)
13021 ffeinfoBasictype bt;
13022 ffeinfoKindtype kt;
13025 assert (expr != NULL);
13027 bt = ffeinfo_basictype (ffebld_info (expr));
13028 kt = ffeinfo_kindtype (ffebld_info (expr));
13029 tree_type = ffecom_tree_type[bt][kt];
13031 switch (ffebld_op (expr))
13033 case FFEBLD_opCONTER:
13034 case FFEBLD_opSYMTER:
13035 case FFEBLD_opARRAYREF:
13036 case FFEBLD_opUPLUS:
13037 case FFEBLD_opPAREN:
13038 case FFEBLD_opUMINUS:
13040 case FFEBLD_opSUBTRACT:
13041 case FFEBLD_opMULTIPLY:
13042 case FFEBLD_opDIVIDE:
13043 case FFEBLD_opPOWER:
13045 case FFEBLD_opFUNCREF:
13046 case FFEBLD_opSUBRREF:
13050 case FFEBLD_opNEQV:
13052 case FFEBLD_opCONVERT:
13059 case FFEBLD_opPERCENT_LOC:
13062 case FFEBLD_opACCTER:
13063 case FFEBLD_opARRTER:
13064 case FFEBLD_opITEM:
13065 case FFEBLD_opSTAR:
13066 case FFEBLD_opBOUNDS:
13067 case FFEBLD_opREPEAT:
13068 case FFEBLD_opLABTER:
13069 case FFEBLD_opLABTOK:
13070 case FFEBLD_opIMPDO:
13071 case FFEBLD_opCONCATENATE:
13072 case FFEBLD_opSUBSTR:
13074 assert ("bad op for ffecom_type_expr" == NULL);
13075 /* Fall through. */
13077 return error_mark_node;
13081 /* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13083 If the PARM_DECL already exists, return it, else create it. It's an
13084 integer_type_node argument for the master function that implements a
13085 subroutine or function with more than one entrypoint and is bound at
13086 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13087 first ENTRY statement, and so on). */
13090 ffecom_which_entrypoint_decl ()
13092 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13094 return ffecom_which_entrypoint_decl_;
13097 /* The following sections consists of private and public functions
13098 that have the same names and perform roughly the same functions
13099 as counterparts in the C front end. Changes in the C front end
13100 might affect how things should be done here. Only functions
13101 needed by the back end should be public here; the rest should
13102 be private (static in the C sense). Functions needed by other
13103 g77 front-end modules should be accessed by them via public
13104 ffecom_* names, which should themselves call private versions
13105 in this section so the private versions are easy to recognize
13106 when upgrading to a new gcc and finding interesting changes
13109 Functions named after rule "foo:" in c-parse.y are named
13110 "bison_rule_foo_" so they are easy to find. */
13113 bison_rule_pushlevel_ ()
13115 emit_line_note (input_filename, lineno);
13117 clear_last_expr ();
13118 expand_start_bindings (0);
13122 bison_rule_compstmt_ ()
13125 int keep = kept_level_p ();
13127 /* Make the temps go away. */
13129 current_binding_level->names = NULL_TREE;
13131 emit_line_note (input_filename, lineno);
13132 expand_end_bindings (getdecls (), keep, 0);
13133 t = poplevel (keep, 1, 0);
13138 /* Return a definition for a builtin function named NAME and whose data type
13139 is TYPE. TYPE should be a function type with argument types.
13140 FUNCTION_CODE tells later passes how to compile calls to this function.
13141 See tree.h for its possible values.
13143 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13144 the name to be called if we can't opencode the function. */
13147 builtin_function (const char *name, tree type, int function_code,
13148 enum built_in_class class,
13149 const char *library_name)
13151 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13152 DECL_EXTERNAL (decl) = 1;
13153 TREE_PUBLIC (decl) = 1;
13155 SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
13156 make_decl_rtl (decl, NULL);
13158 DECL_BUILT_IN_CLASS (decl) = class;
13159 DECL_FUNCTION_CODE (decl) = function_code;
13164 /* Handle when a new declaration NEWDECL
13165 has the same name as an old one OLDDECL
13166 in the same binding contour.
13167 Prints an error message if appropriate.
13169 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13170 Otherwise, return 0. */
13173 duplicate_decls (tree newdecl, tree olddecl)
13175 int types_match = 1;
13176 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13177 && DECL_INITIAL (newdecl) != 0);
13178 tree oldtype = TREE_TYPE (olddecl);
13179 tree newtype = TREE_TYPE (newdecl);
13181 if (olddecl == newdecl)
13184 if (TREE_CODE (newtype) == ERROR_MARK
13185 || TREE_CODE (oldtype) == ERROR_MARK)
13188 /* New decl is completely inconsistent with the old one =>
13189 tell caller to replace the old one.
13190 This is always an error except in the case of shadowing a builtin. */
13191 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13194 /* For real parm decl following a forward decl,
13195 return 1 so old decl will be reused. */
13196 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13197 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13200 /* The new declaration is the same kind of object as the old one.
13201 The declarations may partially match. Print warnings if they don't
13202 match enough. Ultimately, copy most of the information from the new
13203 decl to the old one, and keep using the old one. */
13205 if (TREE_CODE (olddecl) == FUNCTION_DECL
13206 && DECL_BUILT_IN (olddecl))
13208 /* A function declaration for a built-in function. */
13209 if (!TREE_PUBLIC (newdecl))
13211 else if (!types_match)
13213 /* Accept the return type of the new declaration if same modes. */
13214 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13215 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
13217 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13219 /* Function types may be shared, so we can't just modify
13220 the return type of olddecl's function type. */
13222 = build_function_type (newreturntype,
13223 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
13227 TREE_TYPE (olddecl) = newtype;
13233 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13234 && DECL_SOURCE_LINE (olddecl) == 0)
13236 /* A function declaration for a predeclared function
13237 that isn't actually built in. */
13238 if (!TREE_PUBLIC (newdecl))
13240 else if (!types_match)
13242 /* If the types don't match, preserve volatility indication.
13243 Later on, we will discard everything else about the
13244 default declaration. */
13245 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13249 /* Copy all the DECL_... slots specified in the new decl
13250 except for any that we copy here from the old type.
13252 Past this point, we don't change OLDTYPE and NEWTYPE
13253 even if we change the types of NEWDECL and OLDDECL. */
13257 /* Merge the data types specified in the two decls. */
13258 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13259 TREE_TYPE (newdecl)
13260 = TREE_TYPE (olddecl)
13261 = TREE_TYPE (newdecl);
13263 /* Lay the type out, unless already done. */
13264 if (oldtype != TREE_TYPE (newdecl))
13266 if (TREE_TYPE (newdecl) != error_mark_node)
13267 layout_type (TREE_TYPE (newdecl));
13268 if (TREE_CODE (newdecl) != FUNCTION_DECL
13269 && TREE_CODE (newdecl) != TYPE_DECL
13270 && TREE_CODE (newdecl) != CONST_DECL)
13271 layout_decl (newdecl, 0);
13275 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13276 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
13277 DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
13278 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13279 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
13281 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13282 DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
13286 /* Keep the old rtl since we can safely use it. */
13287 COPY_DECL_RTL (olddecl, newdecl);
13289 /* Merge the type qualifiers. */
13290 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13291 && !TREE_THIS_VOLATILE (newdecl))
13292 TREE_THIS_VOLATILE (olddecl) = 0;
13293 if (TREE_READONLY (newdecl))
13294 TREE_READONLY (olddecl) = 1;
13295 if (TREE_THIS_VOLATILE (newdecl))
13297 TREE_THIS_VOLATILE (olddecl) = 1;
13298 if (TREE_CODE (newdecl) == VAR_DECL)
13299 make_var_volatile (newdecl);
13302 /* Keep source location of definition rather than declaration.
13303 Likewise, keep decl at outer scope. */
13304 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13305 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13307 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13308 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
13310 if (DECL_CONTEXT (olddecl) == 0
13311 && TREE_CODE (newdecl) != FUNCTION_DECL)
13312 DECL_CONTEXT (newdecl) = 0;
13315 /* Merge the unused-warning information. */
13316 if (DECL_IN_SYSTEM_HEADER (olddecl))
13317 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13318 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13319 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
13321 /* Merge the initialization information. */
13322 if (DECL_INITIAL (newdecl) == 0)
13323 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13325 /* Merge the section attribute.
13326 We want to issue an error if the sections conflict but that must be
13327 done later in decl_attributes since we are called before attributes
13329 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13330 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
13332 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13334 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13335 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13338 /* If cannot merge, then use the new type and qualifiers,
13339 and don't preserve the old rtl. */
13342 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13343 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13344 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13345 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13348 /* Merge the storage class information. */
13349 /* For functions, static overrides non-static. */
13350 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13352 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13353 /* This is since we don't automatically
13354 copy the attributes of NEWDECL into OLDDECL. */
13355 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13356 /* If this clears `static', clear it in the identifier too. */
13357 if (! TREE_PUBLIC (olddecl))
13358 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13360 if (DECL_EXTERNAL (newdecl))
13362 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13363 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13364 /* An extern decl does not override previous storage class. */
13365 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13369 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13370 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13373 /* If either decl says `inline', this fn is inline,
13374 unless its definition was passed already. */
13375 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13376 DECL_INLINE (olddecl) = 1;
13377 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
13379 /* Get rid of any built-in function if new arg types don't match it
13380 or if we have a function definition. */
13381 if (TREE_CODE (newdecl) == FUNCTION_DECL
13382 && DECL_BUILT_IN (olddecl)
13383 && (!types_match || new_is_definition))
13385 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13386 DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
13389 /* If redeclaring a builtin function, and not a definition,
13391 Also preserve various other info from the definition. */
13392 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13394 if (DECL_BUILT_IN (olddecl))
13396 DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
13397 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13400 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13401 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13402 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13403 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13406 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13407 But preserve olddecl's DECL_UID. */
13409 register unsigned olddecl_uid = DECL_UID (olddecl);
13411 memcpy ((char *) olddecl + sizeof (struct tree_common),
13412 (char *) newdecl + sizeof (struct tree_common),
13413 sizeof (struct tree_decl) - sizeof (struct tree_common));
13414 DECL_UID (olddecl) = olddecl_uid;
13420 /* Finish processing of a declaration;
13421 install its initial value.
13422 If the length of an array type is not known before,
13423 it must be determined now, from the initial value, or it is an error. */
13426 finish_decl (tree decl, tree init, bool is_top_level)
13428 register tree type = TREE_TYPE (decl);
13429 int was_incomplete = (DECL_SIZE (decl) == 0);
13430 bool at_top_level = (current_binding_level == global_binding_level);
13431 bool top_level = is_top_level || at_top_level;
13433 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13435 assert (!is_top_level || !at_top_level);
13437 if (TREE_CODE (decl) == PARM_DECL)
13438 assert (init == NULL_TREE);
13439 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
13440 overlaps DECL_ARG_TYPE. */
13441 else if (init == NULL_TREE)
13442 assert (DECL_INITIAL (decl) == NULL_TREE);
13444 assert (DECL_INITIAL (decl) == error_mark_node);
13446 if (init != NULL_TREE)
13448 if (TREE_CODE (decl) != TYPE_DECL)
13449 DECL_INITIAL (decl) = init;
13452 /* typedef foo = bar; store the type of bar as the type of foo. */
13453 TREE_TYPE (decl) = TREE_TYPE (init);
13454 DECL_INITIAL (decl) = init = 0;
13458 /* Deduce size of array from initialization, if not already known */
13460 if (TREE_CODE (type) == ARRAY_TYPE
13461 && TYPE_DOMAIN (type) == 0
13462 && TREE_CODE (decl) != TYPE_DECL)
13464 assert (top_level);
13465 assert (was_incomplete);
13467 layout_decl (decl, 0);
13470 if (TREE_CODE (decl) == VAR_DECL)
13472 if (DECL_SIZE (decl) == NULL_TREE
13473 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
13474 layout_decl (decl, 0);
13476 if (DECL_SIZE (decl) == NULL_TREE
13477 && (TREE_STATIC (decl)
13479 /* A static variable with an incomplete type is an error if it is
13480 initialized. Also if it is not file scope. Otherwise, let it
13481 through, but if it is not `extern' then it may cause an error
13483 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
13485 /* An automatic variable with an incomplete type is an error. */
13486 !DECL_EXTERNAL (decl)))
13488 assert ("storage size not known" == NULL);
13492 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
13493 && (DECL_SIZE (decl) != 0)
13494 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
13496 assert ("storage size not constant" == NULL);
13501 /* Output the assembler code and/or RTL code for variables and functions,
13502 unless the type is an undefined structure or union. If not, it will get
13503 done when the type is completed. */
13505 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
13507 rest_of_decl_compilation (decl, NULL,
13508 DECL_CONTEXT (decl) == 0,
13511 if (DECL_CONTEXT (decl) != 0)
13513 /* Recompute the RTL of a local array now if it used to be an
13514 incomplete type. */
13516 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
13518 /* If we used it already as memory, it must stay in memory. */
13519 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
13520 /* If it's still incomplete now, no init will save it. */
13521 if (DECL_SIZE (decl) == 0)
13522 DECL_INITIAL (decl) = 0;
13523 expand_decl (decl);
13525 /* Compute and store the initial value. */
13526 if (TREE_CODE (decl) != FUNCTION_DECL)
13527 expand_decl_init (decl);
13530 else if (TREE_CODE (decl) == TYPE_DECL)
13532 rest_of_decl_compilation (decl, NULL,
13533 DECL_CONTEXT (decl) == 0,
13537 /* At the end of a declaration, throw away any variable type sizes of types
13538 defined inside that declaration. There is no use computing them in the
13539 following function definition. */
13540 if (current_binding_level == global_binding_level)
13541 get_pending_sizes ();
13544 /* Finish up a function declaration and compile that function
13545 all the way to assembler language output. The free the storage
13546 for the function definition.
13548 This is called after parsing the body of the function definition.
13550 NESTED is nonzero if the function being finished is nested in another. */
13553 finish_function (int nested)
13555 register tree fndecl = current_function_decl;
13557 assert (fndecl != NULL_TREE);
13558 if (TREE_CODE (fndecl) != ERROR_MARK)
13561 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
13563 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
13566 /* TREE_READONLY (fndecl) = 1;
13567 This caused &foo to be of type ptr-to-const-function
13568 which then got a warning when stored in a ptr-to-function variable. */
13570 poplevel (1, 0, 1);
13572 if (TREE_CODE (fndecl) != ERROR_MARK)
13574 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
13576 /* Must mark the RESULT_DECL as being in this function. */
13578 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
13580 /* Obey `register' declarations if `setjmp' is called in this fn. */
13581 /* Generate rtl for function exit. */
13582 expand_function_end (input_filename, lineno, 0);
13584 /* If this is a nested function, protect the local variables in the stack
13585 above us from being collected while we're compiling this function. */
13587 ggc_push_context ();
13589 /* Run the optimizers and output the assembler code for this function. */
13590 rest_of_compilation (fndecl);
13592 /* Undo the GC context switch. */
13594 ggc_pop_context ();
13597 if (TREE_CODE (fndecl) != ERROR_MARK
13599 && DECL_SAVED_INSNS (fndecl) == 0)
13601 /* Stop pointing to the local nodes about to be freed. */
13602 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13603 function definition. */
13604 /* For a nested function, this is done in pop_f_function_context. */
13605 /* If rest_of_compilation set this to 0, leave it 0. */
13606 if (DECL_INITIAL (fndecl) != 0)
13607 DECL_INITIAL (fndecl) = error_mark_node;
13608 DECL_ARGUMENTS (fndecl) = 0;
13613 /* Let the error reporting routines know that we're outside a function.
13614 For a nested function, this value is used in pop_c_function_context
13615 and then reset via pop_function_context. */
13616 ffecom_outer_function_decl_ = current_function_decl = NULL;
13620 /* Plug-in replacement for identifying the name of a decl and, for a
13621 function, what we call it in diagnostics. For now, "program unit"
13622 should suffice, since it's a bit of a hassle to figure out which
13623 of several kinds of things it is. Note that it could conceivably
13624 be a statement function, which probably isn't really a program unit
13625 per se, but if that comes up, it should be easy to check (being a
13626 nested function and all). */
13628 static const char *
13629 lang_printable_name (tree decl, int v)
13631 /* Just to keep GCC quiet about the unused variable.
13632 In theory, differing values of V should produce different
13637 if (TREE_CODE (decl) == ERROR_MARK)
13638 return "erroneous code";
13639 return IDENTIFIER_POINTER (DECL_NAME (decl));
13643 /* g77's function to print out name of current function that caused
13647 lang_print_error_function (diagnostic_context *context __attribute__((unused)),
13650 static ffeglobal last_g = NULL;
13651 static ffesymbol last_s = NULL;
13656 if ((ffecom_primary_entry_ == NULL)
13657 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
13665 g = ffesymbol_global (ffecom_primary_entry_);
13666 if (ffecom_nested_entry_ == NULL)
13668 s = ffecom_primary_entry_;
13669 switch (ffesymbol_kind (s))
13671 case FFEINFO_kindFUNCTION:
13675 case FFEINFO_kindSUBROUTINE:
13676 kind = "subroutine";
13679 case FFEINFO_kindPROGRAM:
13683 case FFEINFO_kindBLOCKDATA:
13684 kind = "block-data";
13688 kind = ffeinfo_kind_message (ffesymbol_kind (s));
13694 s = ffecom_nested_entry_;
13695 kind = "statement function";
13699 if ((last_g != g) || (last_s != s))
13702 fprintf (stderr, "%s: ", file);
13705 fprintf (stderr, "Outside of any program unit:\n");
13708 const char *name = ffesymbol_text (s);
13710 fprintf (stderr, "In %s `%s':\n", kind, name);
13718 /* Similar to `lookup_name' but look only at current binding level. */
13721 lookup_name_current_level (tree name)
13725 if (current_binding_level == global_binding_level)
13726 return IDENTIFIER_GLOBAL_VALUE (name);
13728 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
13731 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
13732 if (DECL_NAME (t) == name)
13738 /* Create a new `struct binding_level'. */
13740 static struct binding_level *
13741 make_binding_level ()
13744 return (struct binding_level *) xmalloc (sizeof (struct binding_level));
13747 /* Save and restore the variables in this file and elsewhere
13748 that keep track of the progress of compilation of the current function.
13749 Used for nested functions. */
13753 struct f_function *next;
13755 tree shadowed_labels;
13756 struct binding_level *binding_level;
13759 struct f_function *f_function_chain;
13761 /* Restore the variables used during compilation of a C function. */
13764 pop_f_function_context ()
13766 struct f_function *p = f_function_chain;
13769 /* Bring back all the labels that were shadowed. */
13770 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
13771 if (DECL_NAME (TREE_VALUE (link)) != 0)
13772 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
13773 = TREE_VALUE (link);
13775 if (current_function_decl != error_mark_node
13776 && DECL_SAVED_INSNS (current_function_decl) == 0)
13778 /* Stop pointing to the local nodes about to be freed. */
13779 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13780 function definition. */
13781 DECL_INITIAL (current_function_decl) = error_mark_node;
13782 DECL_ARGUMENTS (current_function_decl) = 0;
13785 pop_function_context ();
13787 f_function_chain = p->next;
13789 named_labels = p->named_labels;
13790 shadowed_labels = p->shadowed_labels;
13791 current_binding_level = p->binding_level;
13796 /* Save and reinitialize the variables
13797 used during compilation of a C function. */
13800 push_f_function_context ()
13802 struct f_function *p
13803 = (struct f_function *) xmalloc (sizeof (struct f_function));
13805 push_function_context ();
13807 p->next = f_function_chain;
13808 f_function_chain = p;
13810 p->named_labels = named_labels;
13811 p->shadowed_labels = shadowed_labels;
13812 p->binding_level = current_binding_level;
13816 push_parm_decl (tree parm)
13818 int old_immediate_size_expand = immediate_size_expand;
13820 /* Don't try computing parm sizes now -- wait till fn is called. */
13822 immediate_size_expand = 0;
13824 /* Fill in arg stuff. */
13826 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
13827 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
13828 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
13830 parm = pushdecl (parm);
13832 immediate_size_expand = old_immediate_size_expand;
13834 finish_decl (parm, NULL_TREE, FALSE);
13837 /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
13840 pushdecl_top_level (x)
13844 register struct binding_level *b = current_binding_level;
13845 register tree f = current_function_decl;
13847 current_binding_level = global_binding_level;
13848 current_function_decl = NULL_TREE;
13850 current_binding_level = b;
13851 current_function_decl = f;
13855 /* Store the list of declarations of the current level.
13856 This is done for the parameter declarations of a function being defined,
13857 after they are modified in the light of any missing parameters. */
13863 return current_binding_level->names = decls;
13866 /* Store the parameter declarations into the current function declaration.
13867 This is called after parsing the parameter declarations, before
13868 digesting the body of the function.
13870 For an old-style definition, modify the function's type
13871 to specify at least the number of arguments. */
13874 store_parm_decls (int is_main_program UNUSED)
13876 register tree fndecl = current_function_decl;
13878 if (fndecl == error_mark_node)
13881 /* This is a chain of PARM_DECLs from old-style parm declarations. */
13882 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
13884 /* Initialize the RTL code for the function. */
13886 init_function_start (fndecl, input_filename, lineno);
13888 /* Set up parameters and prepare for return, for the function. */
13890 expand_function_start (fndecl, 0);
13894 start_decl (tree decl, bool is_top_level)
13897 bool at_top_level = (current_binding_level == global_binding_level);
13898 bool top_level = is_top_level || at_top_level;
13900 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13902 assert (!is_top_level || !at_top_level);
13904 if (DECL_INITIAL (decl) != NULL_TREE)
13906 assert (DECL_INITIAL (decl) == error_mark_node);
13907 assert (!DECL_EXTERNAL (decl));
13909 else if (top_level)
13910 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
13912 /* For Fortran, we by default put things in .common when possible. */
13913 DECL_COMMON (decl) = 1;
13915 /* Add this decl to the current binding level. TEM may equal DECL or it may
13916 be a previous decl of the same name. */
13918 tem = pushdecl_top_level (decl);
13920 tem = pushdecl (decl);
13922 /* For a local variable, define the RTL now. */
13924 /* But not if this is a duplicate decl and we preserved the rtl from the
13925 previous one (which may or may not happen). */
13926 && !DECL_RTL_SET_P (tem))
13928 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
13930 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
13931 && DECL_INITIAL (tem) != 0)
13938 /* Create the FUNCTION_DECL for a function definition.
13939 DECLSPECS and DECLARATOR are the parts of the declaration;
13940 they describe the function's name and the type it returns,
13941 but twisted together in a fashion that parallels the syntax of C.
13943 This function creates a binding context for the function body
13944 as well as setting up the FUNCTION_DECL in current_function_decl.
13946 Returns 1 on success. If the DECLARATOR is not suitable for a function
13947 (it defines a datum instead), we return 0, which tells
13948 yyparse to report a parse error.
13950 NESTED is nonzero for a function nested within another function. */
13953 start_function (tree name, tree type, int nested, int public)
13957 int old_immediate_size_expand = immediate_size_expand;
13960 shadowed_labels = 0;
13962 /* Don't expand any sizes in the return type of the function. */
13963 immediate_size_expand = 0;
13968 assert (current_function_decl != NULL_TREE);
13969 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
13973 assert (current_function_decl == NULL_TREE);
13976 if (TREE_CODE (type) == ERROR_MARK)
13977 decl1 = current_function_decl = error_mark_node;
13980 decl1 = build_decl (FUNCTION_DECL,
13983 TREE_PUBLIC (decl1) = public ? 1 : 0;
13985 DECL_INLINE (decl1) = 1;
13986 TREE_STATIC (decl1) = 1;
13987 DECL_EXTERNAL (decl1) = 0;
13989 announce_function (decl1);
13991 /* Make the init_value nonzero so pushdecl knows this is not tentative.
13992 error_mark_node is replaced below (in poplevel) with the BLOCK. */
13993 DECL_INITIAL (decl1) = error_mark_node;
13995 /* Record the decl so that the function name is defined. If we already have
13996 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
13998 current_function_decl = pushdecl (decl1);
14002 ffecom_outer_function_decl_ = current_function_decl;
14005 current_binding_level->prep_state = 2;
14007 if (TREE_CODE (current_function_decl) != ERROR_MARK)
14009 make_decl_rtl (current_function_decl, NULL);
14011 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14012 DECL_RESULT (current_function_decl)
14013 = build_decl (RESULT_DECL, NULL_TREE, restype);
14016 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14017 TREE_ADDRESSABLE (current_function_decl) = 1;
14019 immediate_size_expand = old_immediate_size_expand;
14022 /* Here are the public functions the GNU back end needs. */
14025 convert (type, expr)
14028 register tree e = expr;
14029 register enum tree_code code = TREE_CODE (type);
14031 if (type == TREE_TYPE (e)
14032 || TREE_CODE (e) == ERROR_MARK)
14034 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14035 return fold (build1 (NOP_EXPR, type, e));
14036 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14037 || code == ERROR_MARK)
14038 return error_mark_node;
14039 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14041 assert ("void value not ignored as it ought to be" == NULL);
14042 return error_mark_node;
14044 if (code == VOID_TYPE)
14045 return build1 (CONVERT_EXPR, type, e);
14046 if ((code != RECORD_TYPE)
14047 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14048 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14050 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14051 return fold (convert_to_integer (type, e));
14052 if (code == POINTER_TYPE)
14053 return fold (convert_to_pointer (type, e));
14054 if (code == REAL_TYPE)
14055 return fold (convert_to_real (type, e));
14056 if (code == COMPLEX_TYPE)
14057 return fold (convert_to_complex (type, e));
14058 if (code == RECORD_TYPE)
14059 return fold (ffecom_convert_to_complex_ (type, e));
14061 assert ("conversion to non-scalar type requested" == NULL);
14062 return error_mark_node;
14065 /* integrate_decl_tree calls this function, but since we don't use the
14066 DECL_LANG_SPECIFIC field, this is a no-op. */
14069 copy_lang_decl (node)
14074 /* Return the list of declarations of the current level.
14075 Note that this list is in reverse order unless/until
14076 you nreverse it; and when you do nreverse it, you must
14077 store the result back using `storedecls' or you will lose. */
14082 return current_binding_level->names;
14085 /* Nonzero if we are currently in the global binding level. */
14088 global_bindings_p ()
14090 return current_binding_level == global_binding_level;
14093 /* Print an error message for invalid use of an incomplete type.
14094 VALUE is the expression that was used (or 0 if that isn't known)
14095 and TYPE is the type that was invalid. */
14098 incomplete_type_error (value, type)
14102 if (TREE_CODE (type) == ERROR_MARK)
14105 assert ("incomplete type?!?" == NULL);
14108 /* Mark ARG for GC. */
14110 mark_binding_level (void *arg)
14112 struct binding_level *level = *(struct binding_level **) arg;
14116 ggc_mark_tree (level->names);
14117 ggc_mark_tree (level->blocks);
14118 ggc_mark_tree (level->this_block);
14119 level = level->level_chain;
14124 init_decl_processing ()
14126 static tree *const tree_roots[] = {
14127 ¤t_function_decl,
14129 &ffecom_tree_fun_type_void,
14130 &ffecom_integer_zero_node,
14131 &ffecom_integer_one_node,
14132 &ffecom_tree_subr_type,
14133 &ffecom_tree_ptr_to_subr_type,
14134 &ffecom_tree_blockdata_type,
14135 &ffecom_tree_xargc_,
14136 &ffecom_f2c_integer_type_node,
14137 &ffecom_f2c_ptr_to_integer_type_node,
14138 &ffecom_f2c_address_type_node,
14139 &ffecom_f2c_real_type_node,
14140 &ffecom_f2c_ptr_to_real_type_node,
14141 &ffecom_f2c_doublereal_type_node,
14142 &ffecom_f2c_complex_type_node,
14143 &ffecom_f2c_doublecomplex_type_node,
14144 &ffecom_f2c_longint_type_node,
14145 &ffecom_f2c_logical_type_node,
14146 &ffecom_f2c_flag_type_node,
14147 &ffecom_f2c_ftnlen_type_node,
14148 &ffecom_f2c_ftnlen_zero_node,
14149 &ffecom_f2c_ftnlen_one_node,
14150 &ffecom_f2c_ftnlen_two_node,
14151 &ffecom_f2c_ptr_to_ftnlen_type_node,
14152 &ffecom_f2c_ftnint_type_node,
14153 &ffecom_f2c_ptr_to_ftnint_type_node,
14154 &ffecom_outer_function_decl_,
14155 &ffecom_previous_function_decl_,
14156 &ffecom_which_entrypoint_decl_,
14157 &ffecom_float_zero_,
14158 &ffecom_float_half_,
14159 &ffecom_double_zero_,
14160 &ffecom_double_half_,
14161 &ffecom_func_result_,
14162 &ffecom_func_length_,
14163 &ffecom_multi_type_node_,
14164 &ffecom_multi_retval_,
14172 /* Record our roots. */
14173 for (i = 0; i < ARRAY_SIZE (tree_roots); i++)
14174 ggc_add_tree_root (tree_roots[i], 1);
14175 ggc_add_tree_root (&ffecom_tree_type[0][0],
14176 FFEINFO_basictype*FFEINFO_kindtype);
14177 ggc_add_tree_root (&ffecom_tree_fun_type[0][0],
14178 FFEINFO_basictype*FFEINFO_kindtype);
14179 ggc_add_tree_root (&ffecom_tree_ptr_to_fun_type[0][0],
14180 FFEINFO_basictype*FFEINFO_kindtype);
14181 ggc_add_tree_root (ffecom_gfrt_, FFECOM_gfrt);
14182 ggc_add_root (¤t_binding_level, 1, sizeof current_binding_level,
14183 mark_binding_level);
14184 ggc_add_root (&free_binding_level, 1, sizeof current_binding_level,
14185 mark_binding_level);
14186 ggc_add_root (&tracker_head, 1, sizeof tracker_head, mark_tracker_head);
14192 init_parse (filename)
14193 const char *filename;
14195 /* Open input file. */
14196 if (filename == 0 || !strcmp (filename, "-"))
14199 filename = "stdin";
14202 finput = fopen (filename, "r");
14204 fatal_io_error ("can't open %s", filename);
14206 #ifdef IO_BUFFER_SIZE
14207 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14210 decl_printable_name = lang_printable_name;
14211 print_error_function = lang_print_error_function;
14222 /* Delete the node BLOCK from the current binding level.
14223 This is used for the block inside a stmt expr ({...})
14224 so that the block can be reinserted where appropriate. */
14227 delete_block (block)
14231 if (current_binding_level->blocks == block)
14232 current_binding_level->blocks = TREE_CHAIN (block);
14233 for (t = current_binding_level->blocks; t;)
14235 if (TREE_CHAIN (t) == block)
14236 TREE_CHAIN (t) = TREE_CHAIN (block);
14238 t = TREE_CHAIN (t);
14240 TREE_CHAIN (block) = NULL;
14241 /* Clear TREE_USED which is always set by poplevel.
14242 The flag is set again if insert_block is called. */
14243 TREE_USED (block) = 0;
14247 insert_block (block)
14250 TREE_USED (block) = 1;
14251 current_binding_level->blocks
14252 = chainon (current_binding_level->blocks, block);
14255 /* Each front end provides its own. */
14256 static void ffe_init PARAMS ((void));
14257 static void ffe_finish PARAMS ((void));
14258 static void ffe_init_options PARAMS ((void));
14260 #undef LANG_HOOKS_NAME
14261 #define LANG_HOOKS_NAME "GNU F77"
14262 #undef LANG_HOOKS_INIT
14263 #define LANG_HOOKS_INIT ffe_init
14264 #undef LANG_HOOKS_FINISH
14265 #define LANG_HOOKS_FINISH ffe_finish
14266 #undef LANG_HOOKS_INIT_OPTIONS
14267 #define LANG_HOOKS_INIT_OPTIONS ffe_init_options
14268 #undef LANG_HOOKS_DECODE_OPTION
14269 #define LANG_HOOKS_DECODE_OPTION ffe_decode_option
14271 /* We do not wish to use alias-set based aliasing at all. Used in the
14272 extreme (every object with its own set, with equivalences recorded) it
14273 might be helpful, but there are problems when it comes to inlining. We
14274 get on ok with flag_argument_noalias, and alias-set aliasing does
14275 currently limit how stack slots can be reused, which is a lose. */
14276 #undef LANG_HOOKS_GET_ALIAS_SET
14277 #define LANG_HOOKS_GET_ALIAS_SET hook_get_alias_set_0
14279 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
14281 /* used by print-tree.c */
14284 lang_print_xnode (file, node, indent)
14294 ffe_terminate_0 ();
14296 if (ffe_is_ffedebug ())
14297 malloc_pool_display (malloc_pool_image ());
14301 ffe_init_options ()
14303 /* Set default options for Fortran. */
14304 flag_move_all_movables = 1;
14305 flag_reduce_all_givs = 1;
14306 flag_argument_noalias = 2;
14307 flag_merge_constants = 2;
14308 flag_errno_math = 0;
14309 flag_complex_divide_method = 1;
14315 /* If the file is output from cpp, it should contain a first line
14316 `# 1 "real-filename"', and the current design of gcc (toplev.c
14317 in particular and the way it sets up information relied on by
14318 INCLUDE) requires that we read this now, and store the
14319 "real-filename" info in master_input_filename. Ask the lexer
14320 to try doing this. */
14321 ffelex_hash_kludge (finput);
14325 mark_addressable (exp)
14328 register tree x = exp;
14330 switch (TREE_CODE (x))
14333 case COMPONENT_REF:
14335 x = TREE_OPERAND (x, 0);
14339 TREE_ADDRESSABLE (x) = 1;
14346 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14347 && DECL_NONLOCAL (x))
14349 if (TREE_PUBLIC (x))
14351 assert ("address of global register var requested" == NULL);
14354 assert ("address of register variable requested" == NULL);
14356 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14358 if (TREE_PUBLIC (x))
14360 assert ("address of global register var requested" == NULL);
14363 assert ("address of register var requested" == NULL);
14365 put_var_into_stack (x);
14368 case FUNCTION_DECL:
14369 TREE_ADDRESSABLE (x) = 1;
14370 #if 0 /* poplevel deals with this now. */
14371 if (DECL_CONTEXT (x) == 0)
14372 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14380 /* If DECL has a cleanup, build and return that cleanup here.
14381 This is a callback called by expand_expr. */
14384 maybe_build_cleanup (decl)
14387 /* There are no cleanups in Fortran. */
14391 /* Exit a binding level.
14392 Pop the level off, and restore the state of the identifier-decl mappings
14393 that were in effect when this level was entered.
14395 If KEEP is nonzero, this level had explicit declarations, so
14396 and create a "block" (a BLOCK node) for the level
14397 to record its declarations and subblocks for symbol table output.
14399 If FUNCTIONBODY is nonzero, this level is the body of a function,
14400 so create a block as if KEEP were set and also clear out all
14403 If REVERSE is nonzero, reverse the order of decls before putting
14404 them into the BLOCK. */
14407 poplevel (keep, reverse, functionbody)
14412 register tree link;
14413 /* The chain of decls was accumulated in reverse order.
14414 Put it into forward order, just for cleanliness. */
14416 tree subblocks = current_binding_level->blocks;
14419 int block_previously_created;
14421 /* Get the decls in the order they were written.
14422 Usually current_binding_level->names is in reverse order.
14423 But parameter decls were previously put in forward order. */
14426 current_binding_level->names
14427 = decls = nreverse (current_binding_level->names);
14429 decls = current_binding_level->names;
14431 /* Output any nested inline functions within this block
14432 if they weren't already output. */
14434 for (decl = decls; decl; decl = TREE_CHAIN (decl))
14435 if (TREE_CODE (decl) == FUNCTION_DECL
14436 && ! TREE_ASM_WRITTEN (decl)
14437 && DECL_INITIAL (decl) != 0
14438 && TREE_ADDRESSABLE (decl))
14440 /* If this decl was copied from a file-scope decl
14441 on account of a block-scope extern decl,
14442 propagate TREE_ADDRESSABLE to the file-scope decl.
14444 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
14445 true, since then the decl goes through save_for_inline_copying. */
14446 if (DECL_ABSTRACT_ORIGIN (decl) != 0
14447 && DECL_ABSTRACT_ORIGIN (decl) != decl)
14448 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
14449 else if (DECL_SAVED_INSNS (decl) != 0)
14451 push_function_context ();
14452 output_inline_function (decl);
14453 pop_function_context ();
14457 /* If there were any declarations or structure tags in that level,
14458 or if this level is a function body,
14459 create a BLOCK to record them for the life of this function. */
14462 block_previously_created = (current_binding_level->this_block != 0);
14463 if (block_previously_created)
14464 block = current_binding_level->this_block;
14465 else if (keep || functionbody)
14466 block = make_node (BLOCK);
14469 BLOCK_VARS (block) = decls;
14470 BLOCK_SUBBLOCKS (block) = subblocks;
14473 /* In each subblock, record that this is its superior. */
14475 for (link = subblocks; link; link = TREE_CHAIN (link))
14476 BLOCK_SUPERCONTEXT (link) = block;
14478 /* Clear out the meanings of the local variables of this level. */
14480 for (link = decls; link; link = TREE_CHAIN (link))
14482 if (DECL_NAME (link) != 0)
14484 /* If the ident. was used or addressed via a local extern decl,
14485 don't forget that fact. */
14486 if (DECL_EXTERNAL (link))
14488 if (TREE_USED (link))
14489 TREE_USED (DECL_NAME (link)) = 1;
14490 if (TREE_ADDRESSABLE (link))
14491 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
14493 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
14497 /* If the level being exited is the top level of a function,
14498 check over all the labels, and clear out the current
14499 (function local) meanings of their names. */
14503 /* If this is the top level block of a function,
14504 the vars are the function's parameters.
14505 Don't leave them in the BLOCK because they are
14506 found in the FUNCTION_DECL instead. */
14508 BLOCK_VARS (block) = 0;
14511 /* Pop the current level, and free the structure for reuse. */
14514 register struct binding_level *level = current_binding_level;
14515 current_binding_level = current_binding_level->level_chain;
14517 level->level_chain = free_binding_level;
14518 free_binding_level = level;
14521 /* Dispose of the block that we just made inside some higher level. */
14523 && current_function_decl != error_mark_node)
14524 DECL_INITIAL (current_function_decl) = block;
14527 if (!block_previously_created)
14528 current_binding_level->blocks
14529 = chainon (current_binding_level->blocks, block);
14531 /* If we did not make a block for the level just exited,
14532 any blocks made for inner levels
14533 (since they cannot be recorded as subblocks in that level)
14534 must be carried forward so they will later become subblocks
14535 of something else. */
14536 else if (subblocks)
14537 current_binding_level->blocks
14538 = chainon (current_binding_level->blocks, subblocks);
14541 TREE_USED (block) = 1;
14546 print_lang_decl (file, node, indent)
14554 print_lang_identifier (file, node, indent)
14559 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
14560 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
14564 print_lang_statistics ()
14569 print_lang_type (file, node, indent)
14576 /* Record a decl-node X as belonging to the current lexical scope.
14577 Check for errors (such as an incompatible declaration for the same
14578 name already seen in the same scope).
14580 Returns either X or an old decl for the same name.
14581 If an old decl is returned, it may have been smashed
14582 to agree with what X says. */
14589 register tree name = DECL_NAME (x);
14590 register struct binding_level *b = current_binding_level;
14592 if ((TREE_CODE (x) == FUNCTION_DECL)
14593 && (DECL_INITIAL (x) == 0)
14594 && DECL_EXTERNAL (x))
14595 DECL_CONTEXT (x) = NULL_TREE;
14597 DECL_CONTEXT (x) = current_function_decl;
14601 if (IDENTIFIER_INVENTED (name))
14603 DECL_ARTIFICIAL (x) = 1;
14604 DECL_IN_SYSTEM_HEADER (x) = 1;
14607 t = lookup_name_current_level (name);
14609 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
14611 /* Don't push non-parms onto list for parms until we understand
14612 why we're doing this and whether it works. */
14614 assert ((b == global_binding_level)
14615 || !ffecom_transform_only_dummies_
14616 || TREE_CODE (x) == PARM_DECL);
14618 if ((t != NULL_TREE) && duplicate_decls (x, t))
14621 /* If we are processing a typedef statement, generate a whole new
14622 ..._TYPE node (which will be just an variant of the existing
14623 ..._TYPE node with identical properties) and then install the
14624 TYPE_DECL node generated to represent the typedef name as the
14625 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
14627 The whole point here is to end up with a situation where each and every
14628 ..._TYPE node the compiler creates will be uniquely associated with
14629 AT MOST one node representing a typedef name. This way, even though
14630 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
14631 (i.e. "typedef name") nodes very early on, later parts of the
14632 compiler can always do the reverse translation and get back the
14633 corresponding typedef name. For example, given:
14635 typedef struct S MY_TYPE; MY_TYPE object;
14637 Later parts of the compiler might only know that `object' was of type
14638 `struct S' if it were not for code just below. With this code
14639 however, later parts of the compiler see something like:
14641 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
14643 And they can then deduce (from the node for type struct S') that the
14644 original object declaration was:
14648 Being able to do this is important for proper support of protoize, and
14649 also for generating precise symbolic debugging information which
14650 takes full account of the programmer's (typedef) vocabulary.
14652 Obviously, we don't want to generate a duplicate ..._TYPE node if the
14653 TYPE_DECL node that we are now processing really represents a
14654 standard built-in type.
14656 Since all standard types are effectively declared at line zero in the
14657 source file, we can easily check to see if we are working on a
14658 standard type by checking the current value of lineno. */
14660 if (TREE_CODE (x) == TYPE_DECL)
14662 if (DECL_SOURCE_LINE (x) == 0)
14664 if (TYPE_NAME (TREE_TYPE (x)) == 0)
14665 TYPE_NAME (TREE_TYPE (x)) = x;
14667 else if (TREE_TYPE (x) != error_mark_node)
14669 tree tt = TREE_TYPE (x);
14671 tt = build_type_copy (tt);
14672 TYPE_NAME (tt) = x;
14673 TREE_TYPE (x) = tt;
14677 /* This name is new in its binding level. Install the new declaration
14679 if (b == global_binding_level)
14680 IDENTIFIER_GLOBAL_VALUE (name) = x;
14682 IDENTIFIER_LOCAL_VALUE (name) = x;
14685 /* Put decls on list in reverse order. We will reverse them later if
14687 TREE_CHAIN (x) = b->names;
14693 /* Nonzero if the current level needs to have a BLOCK made. */
14700 for (decl = current_binding_level->names;
14702 decl = TREE_CHAIN (decl))
14704 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
14705 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
14706 /* Currently, there aren't supposed to be non-artificial names
14707 at other than the top block for a function -- they're
14708 believed to always be temps. But it's wise to check anyway. */
14714 /* Enter a new binding level.
14715 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
14716 not for that of tags. */
14719 pushlevel (tag_transparent)
14720 int tag_transparent;
14722 register struct binding_level *newlevel = NULL_BINDING_LEVEL;
14724 assert (! tag_transparent);
14726 if (current_binding_level == global_binding_level)
14731 /* Reuse or create a struct for this binding level. */
14733 if (free_binding_level)
14735 newlevel = free_binding_level;
14736 free_binding_level = free_binding_level->level_chain;
14740 newlevel = make_binding_level ();
14743 /* Add this level to the front of the chain (stack) of levels that
14746 *newlevel = clear_binding_level;
14747 newlevel->level_chain = current_binding_level;
14748 current_binding_level = newlevel;
14751 /* Set the BLOCK node for the innermost scope
14752 (the one we are currently in). */
14756 register tree block;
14758 current_binding_level->this_block = block;
14759 current_binding_level->names = chainon (current_binding_level->names,
14760 BLOCK_VARS (block));
14761 current_binding_level->blocks = chainon (current_binding_level->blocks,
14762 BLOCK_SUBBLOCKS (block));
14765 /* ~~gcc/tree.h *should* declare this, because toplev.c references it. */
14767 /* Can't 'yydebug' a front end not generated by yacc/bison! */
14770 set_yydebug (value)
14774 fprintf (stderr, "warning: no yacc/bison-generated output to debug!\n");
14778 signed_or_unsigned_type (unsignedp, type)
14784 if (! INTEGRAL_TYPE_P (type))
14786 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
14787 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
14788 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
14789 return unsignedp ? unsigned_type_node : integer_type_node;
14790 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
14791 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
14792 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
14793 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
14794 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
14795 return (unsignedp ? long_long_unsigned_type_node
14796 : long_long_integer_type_node);
14798 type2 = type_for_size (TYPE_PRECISION (type), unsignedp);
14799 if (type2 == NULL_TREE)
14809 tree type1 = TYPE_MAIN_VARIANT (type);
14810 ffeinfoKindtype kt;
14813 if (type1 == unsigned_char_type_node || type1 == char_type_node)
14814 return signed_char_type_node;
14815 if (type1 == unsigned_type_node)
14816 return integer_type_node;
14817 if (type1 == short_unsigned_type_node)
14818 return short_integer_type_node;
14819 if (type1 == long_unsigned_type_node)
14820 return long_integer_type_node;
14821 if (type1 == long_long_unsigned_type_node)
14822 return long_long_integer_type_node;
14823 #if 0 /* gcc/c-* files only */
14824 if (type1 == unsigned_intDI_type_node)
14825 return intDI_type_node;
14826 if (type1 == unsigned_intSI_type_node)
14827 return intSI_type_node;
14828 if (type1 == unsigned_intHI_type_node)
14829 return intHI_type_node;
14830 if (type1 == unsigned_intQI_type_node)
14831 return intQI_type_node;
14834 type2 = type_for_size (TYPE_PRECISION (type1), 0);
14835 if (type2 != NULL_TREE)
14838 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
14840 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
14842 if (type1 == type2)
14843 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
14849 /* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
14850 or validate its data type for an `if' or `while' statement or ?..: exp.
14852 This preparation consists of taking the ordinary
14853 representation of an expression expr and producing a valid tree
14854 boolean expression describing whether expr is nonzero. We could
14855 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
14856 but we optimize comparisons, &&, ||, and !.
14858 The resulting type should always be `integer_type_node'. */
14861 truthvalue_conversion (expr)
14864 if (TREE_CODE (expr) == ERROR_MARK)
14867 #if 0 /* This appears to be wrong for C++. */
14868 /* These really should return error_mark_node after 2.4 is stable.
14869 But not all callers handle ERROR_MARK properly. */
14870 switch (TREE_CODE (TREE_TYPE (expr)))
14873 error ("struct type value used where scalar is required");
14874 return integer_zero_node;
14877 error ("union type value used where scalar is required");
14878 return integer_zero_node;
14881 error ("array type value used where scalar is required");
14882 return integer_zero_node;
14889 switch (TREE_CODE (expr))
14891 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14892 or comparison expressions as truth values at this level. */
14894 case COMPONENT_REF:
14895 /* A one-bit unsigned bit-field is already acceptable. */
14896 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
14897 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
14903 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14904 or comparison expressions as truth values at this level. */
14906 if (integer_zerop (TREE_OPERAND (expr, 1)))
14907 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
14909 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
14910 case TRUTH_ANDIF_EXPR:
14911 case TRUTH_ORIF_EXPR:
14912 case TRUTH_AND_EXPR:
14913 case TRUTH_OR_EXPR:
14914 case TRUTH_XOR_EXPR:
14915 TREE_TYPE (expr) = integer_type_node;
14922 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
14925 return real_zerop (expr) ? integer_zero_node : integer_one_node;
14928 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
14929 return build (COMPOUND_EXPR, integer_type_node,
14930 TREE_OPERAND (expr, 0), integer_one_node);
14932 return integer_one_node;
14935 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
14936 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
14938 truthvalue_conversion (TREE_OPERAND (expr, 0)),
14939 truthvalue_conversion (TREE_OPERAND (expr, 1)));
14945 /* These don't change whether an object is non-zero or zero. */
14946 return truthvalue_conversion (TREE_OPERAND (expr, 0));
14950 /* These don't change whether an object is zero or non-zero, but
14951 we can't ignore them if their second arg has side-effects. */
14952 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
14953 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
14954 truthvalue_conversion (TREE_OPERAND (expr, 0)));
14956 return truthvalue_conversion (TREE_OPERAND (expr, 0));
14959 /* Distribute the conversion into the arms of a COND_EXPR. */
14960 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
14961 truthvalue_conversion (TREE_OPERAND (expr, 1)),
14962 truthvalue_conversion (TREE_OPERAND (expr, 2))));
14965 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
14966 since that affects how `default_conversion' will behave. */
14967 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
14968 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
14970 /* fall through... */
14972 /* If this is widening the argument, we can ignore it. */
14973 if (TYPE_PRECISION (TREE_TYPE (expr))
14974 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
14975 return truthvalue_conversion (TREE_OPERAND (expr, 0));
14979 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
14981 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
14982 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
14984 /* fall through... */
14986 /* This and MINUS_EXPR can be changed into a comparison of the
14988 if (TREE_TYPE (TREE_OPERAND (expr, 0))
14989 == TREE_TYPE (TREE_OPERAND (expr, 1)))
14990 return ffecom_2 (NE_EXPR, integer_type_node,
14991 TREE_OPERAND (expr, 0),
14992 TREE_OPERAND (expr, 1));
14993 return ffecom_2 (NE_EXPR, integer_type_node,
14994 TREE_OPERAND (expr, 0),
14995 fold (build1 (NOP_EXPR,
14996 TREE_TYPE (TREE_OPERAND (expr, 0)),
14997 TREE_OPERAND (expr, 1))));
15000 if (integer_onep (TREE_OPERAND (expr, 1)))
15005 #if 0 /* No such thing in Fortran. */
15006 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
15007 warning ("suggest parentheses around assignment used as truth value");
15015 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
15017 ((TREE_SIDE_EFFECTS (expr)
15018 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15020 truthvalue_conversion (ffecom_1 (REALPART_EXPR,
15021 TREE_TYPE (TREE_TYPE (expr)),
15023 truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
15024 TREE_TYPE (TREE_TYPE (expr)),
15027 return ffecom_2 (NE_EXPR, integer_type_node,
15029 convert (TREE_TYPE (expr), integer_zero_node));
15033 type_for_mode (mode, unsignedp)
15034 enum machine_mode mode;
15041 if (mode == TYPE_MODE (integer_type_node))
15042 return unsignedp ? unsigned_type_node : integer_type_node;
15044 if (mode == TYPE_MODE (signed_char_type_node))
15045 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15047 if (mode == TYPE_MODE (short_integer_type_node))
15048 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15050 if (mode == TYPE_MODE (long_integer_type_node))
15051 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15053 if (mode == TYPE_MODE (long_long_integer_type_node))
15054 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
15056 #if HOST_BITS_PER_WIDE_INT >= 64
15057 if (mode == TYPE_MODE (intTI_type_node))
15058 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
15061 if (mode == TYPE_MODE (float_type_node))
15062 return float_type_node;
15064 if (mode == TYPE_MODE (double_type_node))
15065 return double_type_node;
15067 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
15068 return build_pointer_type (char_type_node);
15070 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
15071 return build_pointer_type (integer_type_node);
15073 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
15074 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
15076 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
15077 && (mode == TYPE_MODE (t)))
15079 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
15080 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
15090 type_for_size (bits, unsignedp)
15094 ffeinfoKindtype kt;
15097 if (bits == TYPE_PRECISION (integer_type_node))
15098 return unsignedp ? unsigned_type_node : integer_type_node;
15100 if (bits == TYPE_PRECISION (signed_char_type_node))
15101 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15103 if (bits == TYPE_PRECISION (short_integer_type_node))
15104 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15106 if (bits == TYPE_PRECISION (long_integer_type_node))
15107 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15109 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15110 return (unsignedp ? long_long_unsigned_type_node
15111 : long_long_integer_type_node);
15113 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15115 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15117 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15118 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15126 unsigned_type (type)
15129 tree type1 = TYPE_MAIN_VARIANT (type);
15130 ffeinfoKindtype kt;
15133 if (type1 == signed_char_type_node || type1 == char_type_node)
15134 return unsigned_char_type_node;
15135 if (type1 == integer_type_node)
15136 return unsigned_type_node;
15137 if (type1 == short_integer_type_node)
15138 return short_unsigned_type_node;
15139 if (type1 == long_integer_type_node)
15140 return long_unsigned_type_node;
15141 if (type1 == long_long_integer_type_node)
15142 return long_long_unsigned_type_node;
15143 #if 0 /* gcc/c-* files only */
15144 if (type1 == intDI_type_node)
15145 return unsigned_intDI_type_node;
15146 if (type1 == intSI_type_node)
15147 return unsigned_intSI_type_node;
15148 if (type1 == intHI_type_node)
15149 return unsigned_intHI_type_node;
15150 if (type1 == intQI_type_node)
15151 return unsigned_intQI_type_node;
15154 type2 = type_for_size (TYPE_PRECISION (type1), 1);
15155 if (type2 != NULL_TREE)
15158 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15160 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15162 if (type1 == type2)
15163 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15171 union tree_node *t ATTRIBUTE_UNUSED;
15173 if (TREE_CODE (t) == IDENTIFIER_NODE)
15175 struct lang_identifier *i = (struct lang_identifier *) t;
15176 ggc_mark_tree (IDENTIFIER_GLOBAL_VALUE (i));
15177 ggc_mark_tree (IDENTIFIER_LOCAL_VALUE (i));
15178 ggc_mark_tree (IDENTIFIER_LABEL_VALUE (i));
15180 else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
15181 ggc_mark (TYPE_LANG_SPECIFIC (t));
15184 /* From gcc/cccp.c, the code to handle -I. */
15186 /* Skip leading "./" from a directory name.
15187 This may yield the empty string, which represents the current directory. */
15189 static const char *
15190 skip_redundant_dir_prefix (const char *dir)
15192 while (dir[0] == '.' && dir[1] == '/')
15193 for (dir += 2; *dir == '/'; dir++)
15195 if (dir[0] == '.' && !dir[1])
15200 /* The file_name_map structure holds a mapping of file names for a
15201 particular directory. This mapping is read from the file named
15202 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15203 map filenames on a file system with severe filename restrictions,
15204 such as DOS. The format of the file name map file is just a series
15205 of lines with two tokens on each line. The first token is the name
15206 to map, and the second token is the actual name to use. */
15208 struct file_name_map
15210 struct file_name_map *map_next;
15215 #define FILE_NAME_MAP_FILE "header.gcc"
15217 /* Current maximum length of directory names in the search path
15218 for include files. (Altered as we get more of them.) */
15220 static int max_include_len = 0;
15222 struct file_name_list
15224 struct file_name_list *next;
15226 /* Mapping of file names for this directory. */
15227 struct file_name_map *name_map;
15228 /* Non-zero if name_map is valid. */
15232 static struct file_name_list *include = NULL; /* First dir to search */
15233 static struct file_name_list *last_include = NULL; /* Last in chain */
15235 /* I/O buffer structure.
15236 The `fname' field is nonzero for source files and #include files
15237 and for the dummy text used for -D and -U.
15238 It is zero for rescanning results of macro expansion
15239 and for expanding macro arguments. */
15240 #define INPUT_STACK_MAX 400
15241 static struct file_buf {
15243 /* Filename specified with #line command. */
15244 const char *nominal_fname;
15245 /* Record where in the search path this file was found.
15246 For #include_next. */
15247 struct file_name_list *dir;
15249 ffewhereColumn column;
15250 } instack[INPUT_STACK_MAX];
15252 static int last_error_tick = 0; /* Incremented each time we print it. */
15253 static int input_file_stack_tick = 0; /* Incremented when status changes. */
15255 /* Current nesting level of input sources.
15256 `instack[indepth]' is the level currently being read. */
15257 static int indepth = -1;
15259 typedef struct file_buf FILE_BUF;
15261 /* Nonzero means -I- has been seen,
15262 so don't look for #include "foo" the source-file directory. */
15263 static int ignore_srcdir;
15265 #ifndef INCLUDE_LEN_FUDGE
15266 #define INCLUDE_LEN_FUDGE 0
15269 static void append_include_chain (struct file_name_list *first,
15270 struct file_name_list *last);
15271 static FILE *open_include_file (char *filename,
15272 struct file_name_list *searchptr);
15273 static void print_containing_files (ffebadSeverity sev);
15274 static char *read_filename_string (int ch, FILE *f);
15275 static struct file_name_map *read_name_map (const char *dirname);
15277 /* Append a chain of `struct file_name_list's
15278 to the end of the main include chain.
15279 FIRST is the beginning of the chain to append, and LAST is the end. */
15282 append_include_chain (first, last)
15283 struct file_name_list *first, *last;
15285 struct file_name_list *dir;
15287 if (!first || !last)
15293 last_include->next = first;
15295 for (dir = first; ; dir = dir->next) {
15296 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15297 if (len > max_include_len)
15298 max_include_len = len;
15304 last_include = last;
15307 /* Try to open include file FILENAME. SEARCHPTR is the directory
15308 being tried from the include file search path. This function maps
15309 filenames on file systems based on information read by
15313 open_include_file (filename, searchptr)
15315 struct file_name_list *searchptr;
15317 register struct file_name_map *map;
15318 register char *from;
15321 if (searchptr && ! searchptr->got_name_map)
15323 searchptr->name_map = read_name_map (searchptr->fname
15324 ? searchptr->fname : ".");
15325 searchptr->got_name_map = 1;
15328 /* First check the mapping for the directory we are using. */
15329 if (searchptr && searchptr->name_map)
15332 if (searchptr->fname)
15333 from += strlen (searchptr->fname) + 1;
15334 for (map = searchptr->name_map; map; map = map->map_next)
15336 if (! strcmp (map->map_from, from))
15338 /* Found a match. */
15339 return fopen (map->map_to, "r");
15344 /* Try to find a mapping file for the particular directory we are
15345 looking in. Thus #include <sys/types.h> will look up sys/types.h
15346 in /usr/include/header.gcc and look up types.h in
15347 /usr/include/sys/header.gcc. */
15348 p = strrchr (filename, '/');
15349 #ifdef DIR_SEPARATOR
15350 if (! p) p = strrchr (filename, DIR_SEPARATOR);
15352 char *tmp = strrchr (filename, DIR_SEPARATOR);
15353 if (tmp != NULL && tmp > p) p = tmp;
15359 && searchptr->fname
15360 && strlen (searchptr->fname) == (size_t) (p - filename)
15361 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15363 /* FILENAME is in SEARCHPTR, which we've already checked. */
15364 return fopen (filename, "r");
15370 map = read_name_map (".");
15374 dir = (char *) xmalloc (p - filename + 1);
15375 memcpy (dir, filename, p - filename);
15376 dir[p - filename] = '\0';
15378 map = read_name_map (dir);
15381 for (; map; map = map->map_next)
15382 if (! strcmp (map->map_from, from))
15383 return fopen (map->map_to, "r");
15385 return fopen (filename, "r");
15388 /* Print the file names and line numbers of the #include
15389 commands which led to the current file. */
15392 print_containing_files (ffebadSeverity sev)
15394 FILE_BUF *ip = NULL;
15400 /* If stack of files hasn't changed since we last printed
15401 this info, don't repeat it. */
15402 if (last_error_tick == input_file_stack_tick)
15405 for (i = indepth; i >= 0; i--)
15406 if (instack[i].fname != NULL) {
15411 /* Give up if we don't find a source file. */
15415 /* Find the other, outer source files. */
15416 for (i--; i >= 0; i--)
15417 if (instack[i].fname != NULL)
15423 str1 = "In file included";
15435 ffebad_start_msg ("%A from %B at %0%C", sev);
15436 ffebad_here (0, ip->line, ip->column);
15437 ffebad_string (str1);
15438 ffebad_string (ip->nominal_fname);
15439 ffebad_string (str2);
15443 /* Record we have printed the status as of this time. */
15444 last_error_tick = input_file_stack_tick;
15447 /* Read a space delimited string of unlimited length from a stdio
15451 read_filename_string (ch, f)
15459 set = alloc = xmalloc (len + 1);
15460 if (! ISSPACE (ch))
15463 while ((ch = getc (f)) != EOF && ! ISSPACE (ch))
15465 if (set - alloc == len)
15468 alloc = xrealloc (alloc, len + 1);
15469 set = alloc + len / 2;
15479 /* Read the file name map file for DIRNAME. */
15481 static struct file_name_map *
15482 read_name_map (dirname)
15483 const char *dirname;
15485 /* This structure holds a linked list of file name maps, one per
15487 struct file_name_map_list
15489 struct file_name_map_list *map_list_next;
15490 char *map_list_name;
15491 struct file_name_map *map_list_map;
15493 static struct file_name_map_list *map_list;
15494 register struct file_name_map_list *map_list_ptr;
15498 int separator_needed;
15500 dirname = skip_redundant_dir_prefix (dirname);
15502 for (map_list_ptr = map_list; map_list_ptr;
15503 map_list_ptr = map_list_ptr->map_list_next)
15504 if (! strcmp (map_list_ptr->map_list_name, dirname))
15505 return map_list_ptr->map_list_map;
15507 map_list_ptr = ((struct file_name_map_list *)
15508 xmalloc (sizeof (struct file_name_map_list)));
15509 map_list_ptr->map_list_name = xstrdup (dirname);
15510 map_list_ptr->map_list_map = NULL;
15512 dirlen = strlen (dirname);
15513 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
15514 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
15515 strcpy (name, dirname);
15516 name[dirlen] = '/';
15517 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
15518 f = fopen (name, "r");
15521 map_list_ptr->map_list_map = NULL;
15526 while ((ch = getc (f)) != EOF)
15529 struct file_name_map *ptr;
15533 from = read_filename_string (ch, f);
15534 while ((ch = getc (f)) != EOF && ISSPACE (ch) && ch != '\n')
15536 to = read_filename_string (ch, f);
15538 ptr = ((struct file_name_map *)
15539 xmalloc (sizeof (struct file_name_map)));
15540 ptr->map_from = from;
15542 /* Make the real filename absolute. */
15547 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
15548 strcpy (ptr->map_to, dirname);
15549 ptr->map_to[dirlen] = '/';
15550 strcpy (ptr->map_to + dirlen + separator_needed, to);
15554 ptr->map_next = map_list_ptr->map_list_map;
15555 map_list_ptr->map_list_map = ptr;
15557 while ((ch = getc (f)) != '\n')
15564 map_list_ptr->map_list_next = map_list;
15565 map_list = map_list_ptr;
15567 return map_list_ptr->map_list_map;
15571 ffecom_file_ (const char *name)
15575 /* Do partial setup of input buffer for the sake of generating
15576 early #line directives (when -g is in effect). */
15578 fp = &instack[++indepth];
15579 memset ((char *) fp, 0, sizeof (FILE_BUF));
15582 fp->nominal_fname = fp->fname = name;
15586 ffecom_close_include_ (FILE *f)
15591 input_file_stack_tick++;
15593 ffewhere_line_kill (instack[indepth].line);
15594 ffewhere_column_kill (instack[indepth].column);
15598 ffecom_decode_include_option_ (char *spec)
15600 struct file_name_list *dirtmp;
15602 if (! ignore_srcdir && !strcmp (spec, "-"))
15606 dirtmp = (struct file_name_list *)
15607 xmalloc (sizeof (struct file_name_list));
15608 dirtmp->next = 0; /* New one goes on the end */
15609 dirtmp->fname = spec;
15610 dirtmp->got_name_map = 0;
15612 error ("Directory name must immediately follow -I");
15614 append_include_chain (dirtmp, dirtmp);
15619 /* Open INCLUDEd file. */
15622 ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
15625 size_t flen = strlen (fbeg);
15626 struct file_name_list *search_start = include; /* Chain of dirs to search */
15627 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
15628 struct file_name_list *searchptr = 0;
15629 char *fname; /* Dynamically allocated fname buffer */
15636 dsp[0].fname = NULL;
15638 /* If -I- was specified, don't search current dir, only spec'd ones. */
15639 if (!ignore_srcdir)
15641 for (fp = &instack[indepth]; fp >= instack; fp--)
15647 if ((nam = fp->nominal_fname) != NULL)
15649 /* Found a named file. Figure out dir of the file,
15650 and put it in front of the search list. */
15651 dsp[0].next = search_start;
15652 search_start = dsp;
15654 ep = strrchr (nam, '/');
15655 #ifdef DIR_SEPARATOR
15656 if (ep == NULL) ep = strrchr (nam, DIR_SEPARATOR);
15658 char *tmp = strrchr (nam, DIR_SEPARATOR);
15659 if (tmp != NULL && tmp > ep) ep = tmp;
15663 ep = strrchr (nam, ']');
15664 if (ep == NULL) ep = strrchr (nam, '>');
15665 if (ep == NULL) ep = strrchr (nam, ':');
15666 if (ep != NULL) ep++;
15671 dsp[0].fname = (char *) xmalloc (n + 1);
15672 strncpy (dsp[0].fname, nam, n);
15673 dsp[0].fname[n] = '\0';
15674 if (n + INCLUDE_LEN_FUDGE > max_include_len)
15675 max_include_len = n + INCLUDE_LEN_FUDGE;
15678 dsp[0].fname = NULL; /* Current directory */
15679 dsp[0].got_name_map = 0;
15685 /* Allocate this permanently, because it gets stored in the definitions
15687 fname = xmalloc (max_include_len + flen + 4);
15688 /* + 2 above for slash and terminating null. */
15689 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
15692 /* If specified file name is absolute, just open it. */
15695 #ifdef DIR_SEPARATOR
15696 || *fbeg == DIR_SEPARATOR
15700 strncpy (fname, (char *) fbeg, flen);
15702 f = open_include_file (fname, NULL);
15708 /* Search directory path, trying to open the file.
15709 Copy each filename tried into FNAME. */
15711 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
15713 if (searchptr->fname)
15715 /* The empty string in a search path is ignored.
15716 This makes it possible to turn off entirely
15717 a standard piece of the list. */
15718 if (searchptr->fname[0] == 0)
15720 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
15721 if (fname[0] && fname[strlen (fname) - 1] != '/')
15722 strcat (fname, "/");
15723 fname[strlen (fname) + flen] = 0;
15728 strncat (fname, fbeg, flen);
15730 /* Change this 1/2 Unix 1/2 VMS file specification into a
15731 full VMS file specification */
15732 if (searchptr->fname && (searchptr->fname[0] != 0))
15734 /* Fix up the filename */
15735 hack_vms_include_specification (fname);
15739 /* This is a normal VMS filespec, so use it unchanged. */
15740 strncpy (fname, (char *) fbeg, flen);
15742 #if 0 /* Not for g77. */
15743 /* if it's '#include filename', add the missing .h */
15744 if (strchr (fname, '.') == NULL)
15745 strcat (fname, ".h");
15749 f = open_include_file (fname, searchptr);
15751 if (f == NULL && errno == EACCES)
15753 print_containing_files (FFEBAD_severityWARNING);
15754 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
15755 FFEBAD_severityWARNING);
15756 ffebad_string (fname);
15757 ffebad_here (0, l, c);
15768 /* A file that was not found. */
15770 strncpy (fname, (char *) fbeg, flen);
15772 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
15773 ffebad_start (FFEBAD_OPEN_INCLUDE);
15774 ffebad_here (0, l, c);
15775 ffebad_string (fname);
15779 if (dsp[0].fname != NULL)
15780 free (dsp[0].fname);
15785 if (indepth >= (INPUT_STACK_MAX - 1))
15787 print_containing_files (FFEBAD_severityFATAL);
15788 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
15789 FFEBAD_severityFATAL);
15790 ffebad_string (fname);
15791 ffebad_here (0, l, c);
15796 instack[indepth].line = ffewhere_line_use (l);
15797 instack[indepth].column = ffewhere_column_use (c);
15799 fp = &instack[indepth + 1];
15800 memset ((char *) fp, 0, sizeof (FILE_BUF));
15801 fp->nominal_fname = fp->fname = fname;
15802 fp->dir = searchptr;
15805 input_file_stack_tick++;
15810 /**INDENT* (Do not reformat this comment even with -fca option.)
15811 Data-gathering files: Given the source file listed below, compiled with
15812 f2c I obtained the output file listed after that, and from the output
15813 file I derived the above code.
15815 -------- (begin input file to f2c)
15821 double precision D1,D2
15823 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
15850 c FFEINTRIN_impACOS
15851 call fooR(ACOS(R1))
15852 c FFEINTRIN_impAIMAG
15853 call fooR(AIMAG(C1))
15854 c FFEINTRIN_impAINT
15855 call fooR(AINT(R1))
15856 c FFEINTRIN_impALOG
15857 call fooR(ALOG(R1))
15858 c FFEINTRIN_impALOG10
15859 call fooR(ALOG10(R1))
15860 c FFEINTRIN_impAMAX0
15861 call fooR(AMAX0(I1,I2))
15862 c FFEINTRIN_impAMAX1
15863 call fooR(AMAX1(R1,R2))
15864 c FFEINTRIN_impAMIN0
15865 call fooR(AMIN0(I1,I2))
15866 c FFEINTRIN_impAMIN1
15867 call fooR(AMIN1(R1,R2))
15868 c FFEINTRIN_impAMOD
15869 call fooR(AMOD(R1,R2))
15870 c FFEINTRIN_impANINT
15871 call fooR(ANINT(R1))
15872 c FFEINTRIN_impASIN
15873 call fooR(ASIN(R1))
15874 c FFEINTRIN_impATAN
15875 call fooR(ATAN(R1))
15876 c FFEINTRIN_impATAN2
15877 call fooR(ATAN2(R1,R2))
15878 c FFEINTRIN_impCABS
15879 call fooR(CABS(C1))
15880 c FFEINTRIN_impCCOS
15881 call fooC(CCOS(C1))
15882 c FFEINTRIN_impCEXP
15883 call fooC(CEXP(C1))
15884 c FFEINTRIN_impCHAR
15885 call fooA(CHAR(I1))
15886 c FFEINTRIN_impCLOG
15887 call fooC(CLOG(C1))
15888 c FFEINTRIN_impCONJG
15889 call fooC(CONJG(C1))
15892 c FFEINTRIN_impCOSH
15893 call fooR(COSH(R1))
15894 c FFEINTRIN_impCSIN
15895 call fooC(CSIN(C1))
15896 c FFEINTRIN_impCSQRT
15897 call fooC(CSQRT(C1))
15898 c FFEINTRIN_impDABS
15899 call fooD(DABS(D1))
15900 c FFEINTRIN_impDACOS
15901 call fooD(DACOS(D1))
15902 c FFEINTRIN_impDASIN
15903 call fooD(DASIN(D1))
15904 c FFEINTRIN_impDATAN
15905 call fooD(DATAN(D1))
15906 c FFEINTRIN_impDATAN2
15907 call fooD(DATAN2(D1,D2))
15908 c FFEINTRIN_impDCOS
15909 call fooD(DCOS(D1))
15910 c FFEINTRIN_impDCOSH
15911 call fooD(DCOSH(D1))
15912 c FFEINTRIN_impDDIM
15913 call fooD(DDIM(D1,D2))
15914 c FFEINTRIN_impDEXP
15915 call fooD(DEXP(D1))
15917 call fooR(DIM(R1,R2))
15918 c FFEINTRIN_impDINT
15919 call fooD(DINT(D1))
15920 c FFEINTRIN_impDLOG
15921 call fooD(DLOG(D1))
15922 c FFEINTRIN_impDLOG10
15923 call fooD(DLOG10(D1))
15924 c FFEINTRIN_impDMAX1
15925 call fooD(DMAX1(D1,D2))
15926 c FFEINTRIN_impDMIN1
15927 call fooD(DMIN1(D1,D2))
15928 c FFEINTRIN_impDMOD
15929 call fooD(DMOD(D1,D2))
15930 c FFEINTRIN_impDNINT
15931 call fooD(DNINT(D1))
15932 c FFEINTRIN_impDPROD
15933 call fooD(DPROD(R1,R2))
15934 c FFEINTRIN_impDSIGN
15935 call fooD(DSIGN(D1,D2))
15936 c FFEINTRIN_impDSIN
15937 call fooD(DSIN(D1))
15938 c FFEINTRIN_impDSINH
15939 call fooD(DSINH(D1))
15940 c FFEINTRIN_impDSQRT
15941 call fooD(DSQRT(D1))
15942 c FFEINTRIN_impDTAN
15943 call fooD(DTAN(D1))
15944 c FFEINTRIN_impDTANH
15945 call fooD(DTANH(D1))
15948 c FFEINTRIN_impIABS
15949 call fooI(IABS(I1))
15950 c FFEINTRIN_impICHAR
15951 call fooI(ICHAR(A1))
15952 c FFEINTRIN_impIDIM
15953 call fooI(IDIM(I1,I2))
15954 c FFEINTRIN_impIDNINT
15955 call fooI(IDNINT(D1))
15956 c FFEINTRIN_impINDEX
15957 call fooI(INDEX(A1,A2))
15958 c FFEINTRIN_impISIGN
15959 call fooI(ISIGN(I1,I2))
15963 call fooL(LGE(A1,A2))
15965 call fooL(LGT(A1,A2))
15967 call fooL(LLE(A1,A2))
15969 call fooL(LLT(A1,A2))
15970 c FFEINTRIN_impMAX0
15971 call fooI(MAX0(I1,I2))
15972 c FFEINTRIN_impMAX1
15973 call fooI(MAX1(R1,R2))
15974 c FFEINTRIN_impMIN0
15975 call fooI(MIN0(I1,I2))
15976 c FFEINTRIN_impMIN1
15977 call fooI(MIN1(R1,R2))
15979 call fooI(MOD(I1,I2))
15980 c FFEINTRIN_impNINT
15981 call fooI(NINT(R1))
15982 c FFEINTRIN_impSIGN
15983 call fooR(SIGN(R1,R2))
15986 c FFEINTRIN_impSINH
15987 call fooR(SINH(R1))
15988 c FFEINTRIN_impSQRT
15989 call fooR(SQRT(R1))
15992 c FFEINTRIN_impTANH
15993 call fooR(TANH(R1))
15994 c FFEINTRIN_imp_CMPLX_C
15995 call fooC(cmplx(C1,C2))
15996 c FFEINTRIN_imp_CMPLX_D
15997 call fooZ(cmplx(D1,D2))
15998 c FFEINTRIN_imp_CMPLX_I
15999 call fooC(cmplx(I1,I2))
16000 c FFEINTRIN_imp_CMPLX_R
16001 call fooC(cmplx(R1,R2))
16002 c FFEINTRIN_imp_DBLE_C
16003 call fooD(dble(C1))
16004 c FFEINTRIN_imp_DBLE_D
16005 call fooD(dble(D1))
16006 c FFEINTRIN_imp_DBLE_I
16007 call fooD(dble(I1))
16008 c FFEINTRIN_imp_DBLE_R
16009 call fooD(dble(R1))
16010 c FFEINTRIN_imp_INT_C
16012 c FFEINTRIN_imp_INT_D
16014 c FFEINTRIN_imp_INT_I
16016 c FFEINTRIN_imp_INT_R
16018 c FFEINTRIN_imp_REAL_C
16019 call fooR(real(C1))
16020 c FFEINTRIN_imp_REAL_D
16021 call fooR(real(D1))
16022 c FFEINTRIN_imp_REAL_I
16023 call fooR(real(I1))
16024 c FFEINTRIN_imp_REAL_R
16025 call fooR(real(R1))
16027 c FFEINTRIN_imp_INT_D:
16029 c FFEINTRIN_specIDINT
16030 call fooI(IDINT(D1))
16032 c FFEINTRIN_imp_INT_R:
16034 c FFEINTRIN_specIFIX
16035 call fooI(IFIX(R1))
16036 c FFEINTRIN_specINT
16039 c FFEINTRIN_imp_REAL_D:
16041 c FFEINTRIN_specSNGL
16042 call fooR(SNGL(D1))
16044 c FFEINTRIN_imp_REAL_I:
16046 c FFEINTRIN_specFLOAT
16047 call fooR(FLOAT(I1))
16048 c FFEINTRIN_specREAL
16049 call fooR(REAL(I1))
16052 -------- (end input file to f2c)
16054 -------- (begin output from providing above input file as input to:
16055 -------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
16056 -------- -e "s:^#.*$::g"')
16058 // -- translated by f2c (version 19950223).
16059 You must link the resulting object file with the libraries:
16060 -lf2c -lm (in that order)
16064 // f2c.h -- Standard Fortran to C header file //
16066 /// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
16068 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
16073 // F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
16074 // we assume short, float are OK //
16075 typedef long int // long int // integer;
16076 typedef char *address;
16077 typedef short int shortint;
16078 typedef float real;
16079 typedef double doublereal;
16080 typedef struct { real r, i; } complex;
16081 typedef struct { doublereal r, i; } doublecomplex;
16082 typedef long int // long int // logical;
16083 typedef short int shortlogical;
16084 typedef char logical1;
16085 typedef char integer1;
16086 // typedef long long longint; // // system-dependent //
16091 // Extern is for use with -E //
16105 typedef long int // int or long int // flag;
16106 typedef long int // int or long int // ftnlen;
16107 typedef long int // int or long int // ftnint;
16110 //external read, write//
16119 //internal read, write//
16149 //rewind, backspace, endfile//
16161 ftnint *inex; //parameters in standard's order//
16187 union Multitype { // for multiple entry points //
16198 typedef union Multitype Multitype;
16200 typedef long Long; // No longer used; formerly in Namelist //
16202 struct Vardesc { // for Namelist //
16208 typedef struct Vardesc Vardesc;
16215 typedef struct Namelist Namelist;
16224 // procedure parameter types for -A and -C++ //
16229 typedef int // Unknown procedure type // (*U_fp)();
16230 typedef shortint (*J_fp)();
16231 typedef integer (*I_fp)();
16232 typedef real (*R_fp)();
16233 typedef doublereal (*D_fp)(), (*E_fp)();
16234 typedef // Complex // void (*C_fp)();
16235 typedef // Double Complex // void (*Z_fp)();
16236 typedef logical (*L_fp)();
16237 typedef shortlogical (*K_fp)();
16238 typedef // Character // void (*H_fp)();
16239 typedef // Subroutine // int (*S_fp)();
16241 // E_fp is for real functions when -R is not specified //
16242 typedef void C_f; // complex function //
16243 typedef void H_f; // character function //
16244 typedef void Z_f; // double complex function //
16245 typedef doublereal E_f; // real function with -R not specified //
16247 // undef any lower-case symbols that your C compiler predefines, e.g.: //
16250 // (No such symbols should be defined in a strict ANSI C compiler.
16251 We can avoid trouble with f2c-translated code by using
16252 gcc -ansi [-traditional].) //
16276 // Main program // MAIN__()
16278 // System generated locals //
16281 doublereal d__1, d__2;
16283 doublecomplex z__1, z__2, z__3;
16287 // Builtin functions //
16290 double pow_ri(), pow_di();
16294 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16295 asin(), atan(), atan2(), c_abs();
16296 void c_cos(), c_exp(), c_log(), r_cnjg();
16297 double cos(), cosh();
16298 void c_sin(), c_sqrt();
16299 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16300 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16301 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16302 logical l_ge(), l_gt(), l_le(), l_lt();
16306 // Local variables //
16307 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16308 fool_(), fooz_(), getem_();
16309 static char a1[10], a2[10];
16310 static complex c1, c2;
16311 static doublereal d1, d2;
16312 static integer i1, i2;
16313 static real r1, r2;
16316 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16324 d__1 = (doublereal) i1;
16325 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16335 c_div(&q__1, &c1, &c2);
16337 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16339 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16342 i__1 = pow_ii(&i1, &i2);
16344 r__1 = pow_ri(&r1, &i1);
16346 d__1 = pow_di(&d1, &i1);
16348 pow_ci(&q__1, &c1, &i1);
16350 d__1 = (doublereal) r1;
16351 d__2 = (doublereal) r2;
16352 r__1 = pow_dd(&d__1, &d__2);
16354 d__2 = (doublereal) r1;
16355 d__1 = pow_dd(&d__2, &d1);
16357 d__1 = pow_dd(&d1, &d2);
16359 d__2 = (doublereal) r1;
16360 d__1 = pow_dd(&d1, &d__2);
16362 z__2.r = c1.r, z__2.i = c1.i;
16363 z__3.r = c2.r, z__3.i = c2.i;
16364 pow_zz(&z__1, &z__2, &z__3);
16365 q__1.r = z__1.r, q__1.i = z__1.i;
16367 z__2.r = c1.r, z__2.i = c1.i;
16368 z__3.r = r1, z__3.i = 0.;
16369 pow_zz(&z__1, &z__2, &z__3);
16370 q__1.r = z__1.r, q__1.i = z__1.i;
16372 z__2.r = c1.r, z__2.i = c1.i;
16373 z__3.r = d1, z__3.i = 0.;
16374 pow_zz(&z__1, &z__2, &z__3);
16376 // FFEINTRIN_impABS //
16377 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
16379 // FFEINTRIN_impACOS //
16382 // FFEINTRIN_impAIMAG //
16383 r__1 = r_imag(&c1);
16385 // FFEINTRIN_impAINT //
16388 // FFEINTRIN_impALOG //
16391 // FFEINTRIN_impALOG10 //
16392 r__1 = r_lg10(&r1);
16394 // FFEINTRIN_impAMAX0 //
16395 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16397 // FFEINTRIN_impAMAX1 //
16398 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16400 // FFEINTRIN_impAMIN0 //
16401 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16403 // FFEINTRIN_impAMIN1 //
16404 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16406 // FFEINTRIN_impAMOD //
16407 r__1 = r_mod(&r1, &r2);
16409 // FFEINTRIN_impANINT //
16410 r__1 = r_nint(&r1);
16412 // FFEINTRIN_impASIN //
16415 // FFEINTRIN_impATAN //
16418 // FFEINTRIN_impATAN2 //
16419 r__1 = atan2(r1, r2);
16421 // FFEINTRIN_impCABS //
16424 // FFEINTRIN_impCCOS //
16427 // FFEINTRIN_impCEXP //
16430 // FFEINTRIN_impCHAR //
16431 *(unsigned char *)&ch__1[0] = i1;
16433 // FFEINTRIN_impCLOG //
16436 // FFEINTRIN_impCONJG //
16437 r_cnjg(&q__1, &c1);
16439 // FFEINTRIN_impCOS //
16442 // FFEINTRIN_impCOSH //
16445 // FFEINTRIN_impCSIN //
16448 // FFEINTRIN_impCSQRT //
16449 c_sqrt(&q__1, &c1);
16451 // FFEINTRIN_impDABS //
16452 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
16454 // FFEINTRIN_impDACOS //
16457 // FFEINTRIN_impDASIN //
16460 // FFEINTRIN_impDATAN //
16463 // FFEINTRIN_impDATAN2 //
16464 d__1 = atan2(d1, d2);
16466 // FFEINTRIN_impDCOS //
16469 // FFEINTRIN_impDCOSH //
16472 // FFEINTRIN_impDDIM //
16473 d__1 = d_dim(&d1, &d2);
16475 // FFEINTRIN_impDEXP //
16478 // FFEINTRIN_impDIM //
16479 r__1 = r_dim(&r1, &r2);
16481 // FFEINTRIN_impDINT //
16484 // FFEINTRIN_impDLOG //
16487 // FFEINTRIN_impDLOG10 //
16488 d__1 = d_lg10(&d1);
16490 // FFEINTRIN_impDMAX1 //
16491 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
16493 // FFEINTRIN_impDMIN1 //
16494 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
16496 // FFEINTRIN_impDMOD //
16497 d__1 = d_mod(&d1, &d2);
16499 // FFEINTRIN_impDNINT //
16500 d__1 = d_nint(&d1);
16502 // FFEINTRIN_impDPROD //
16503 d__1 = (doublereal) r1 * r2;
16505 // FFEINTRIN_impDSIGN //
16506 d__1 = d_sign(&d1, &d2);
16508 // FFEINTRIN_impDSIN //
16511 // FFEINTRIN_impDSINH //
16514 // FFEINTRIN_impDSQRT //
16517 // FFEINTRIN_impDTAN //
16520 // FFEINTRIN_impDTANH //
16523 // FFEINTRIN_impEXP //
16526 // FFEINTRIN_impIABS //
16527 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
16529 // FFEINTRIN_impICHAR //
16530 i__1 = *(unsigned char *)a1;
16532 // FFEINTRIN_impIDIM //
16533 i__1 = i_dim(&i1, &i2);
16535 // FFEINTRIN_impIDNINT //
16536 i__1 = i_dnnt(&d1);
16538 // FFEINTRIN_impINDEX //
16539 i__1 = i_indx(a1, a2, 10L, 10L);
16541 // FFEINTRIN_impISIGN //
16542 i__1 = i_sign(&i1, &i2);
16544 // FFEINTRIN_impLEN //
16545 i__1 = i_len(a1, 10L);
16547 // FFEINTRIN_impLGE //
16548 L__1 = l_ge(a1, a2, 10L, 10L);
16550 // FFEINTRIN_impLGT //
16551 L__1 = l_gt(a1, a2, 10L, 10L);
16553 // FFEINTRIN_impLLE //
16554 L__1 = l_le(a1, a2, 10L, 10L);
16556 // FFEINTRIN_impLLT //
16557 L__1 = l_lt(a1, a2, 10L, 10L);
16559 // FFEINTRIN_impMAX0 //
16560 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16562 // FFEINTRIN_impMAX1 //
16563 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16565 // FFEINTRIN_impMIN0 //
16566 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16568 // FFEINTRIN_impMIN1 //
16569 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16571 // FFEINTRIN_impMOD //
16574 // FFEINTRIN_impNINT //
16575 i__1 = i_nint(&r1);
16577 // FFEINTRIN_impSIGN //
16578 r__1 = r_sign(&r1, &r2);
16580 // FFEINTRIN_impSIN //
16583 // FFEINTRIN_impSINH //
16586 // FFEINTRIN_impSQRT //
16589 // FFEINTRIN_impTAN //
16592 // FFEINTRIN_impTANH //
16595 // FFEINTRIN_imp_CMPLX_C //
16598 q__1.r = r__1, q__1.i = r__2;
16600 // FFEINTRIN_imp_CMPLX_D //
16601 z__1.r = d1, z__1.i = d2;
16603 // FFEINTRIN_imp_CMPLX_I //
16606 q__1.r = r__1, q__1.i = r__2;
16608 // FFEINTRIN_imp_CMPLX_R //
16609 q__1.r = r1, q__1.i = r2;
16611 // FFEINTRIN_imp_DBLE_C //
16612 d__1 = (doublereal) c1.r;
16614 // FFEINTRIN_imp_DBLE_D //
16617 // FFEINTRIN_imp_DBLE_I //
16618 d__1 = (doublereal) i1;
16620 // FFEINTRIN_imp_DBLE_R //
16621 d__1 = (doublereal) r1;
16623 // FFEINTRIN_imp_INT_C //
16624 i__1 = (integer) c1.r;
16626 // FFEINTRIN_imp_INT_D //
16627 i__1 = (integer) d1;
16629 // FFEINTRIN_imp_INT_I //
16632 // FFEINTRIN_imp_INT_R //
16633 i__1 = (integer) r1;
16635 // FFEINTRIN_imp_REAL_C //
16638 // FFEINTRIN_imp_REAL_D //
16641 // FFEINTRIN_imp_REAL_I //
16644 // FFEINTRIN_imp_REAL_R //
16648 // FFEINTRIN_imp_INT_D: //
16650 // FFEINTRIN_specIDINT //
16651 i__1 = (integer) d1;
16654 // FFEINTRIN_imp_INT_R: //
16656 // FFEINTRIN_specIFIX //
16657 i__1 = (integer) r1;
16659 // FFEINTRIN_specINT //
16660 i__1 = (integer) r1;
16663 // FFEINTRIN_imp_REAL_D: //
16665 // FFEINTRIN_specSNGL //
16669 // FFEINTRIN_imp_REAL_I: //
16671 // FFEINTRIN_specFLOAT //
16674 // FFEINTRIN_specREAL //
16680 -------- (end output file from f2c)