1 /* com.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by James Craig Burley.
6 This file is part of GNU Fortran.
8 GNU Fortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU Fortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Fortran; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 Contains compiler-specific functions.
32 /* Understanding this module means understanding the interface between
33 the g77 front end and the gcc back end (or, perhaps, some other
34 back end). In here are the functions called by the front end proper
35 to notify whatever back end is in place about certain things, and
36 also the back-end-specific functions. It's a bear to deal with, so
37 lately I've been trying to simplify things, especially with regard
38 to the gcc-back-end-specific stuff.
40 Building expressions generally seems quite easy, but building decls
41 has been challenging and is undergoing revision. gcc has several
44 TYPE_DECL -- a type (int, float, struct, function, etc.)
45 CONST_DECL -- a constant of some type other than function
46 LABEL_DECL -- a variable or a constant?
47 PARM_DECL -- an argument to a function (a variable that is a dummy)
48 RESULT_DECL -- the return value of a function (a variable)
49 VAR_DECL -- other variable (can hold a ptr-to-function, struct, int, etc.)
50 FUNCTION_DECL -- a function (either the actual function or an extern ref)
51 FIELD_DECL -- a field in a struct or union (goes into types)
53 g77 has a set of functions that somewhat parallels the gcc front end
54 when it comes to building decls:
56 Internal Function (one we define, not just declare as extern):
57 if (is_nested) push_f_function_context ();
58 start_function (get_identifier ("function_name"), function_type,
59 is_nested, is_public);
60 // for each arg, build PARM_DECL and call push_parm_decl (decl) with it;
61 store_parm_decls (is_main_program);
62 ffecom_start_compstmt ();
63 // for stmts and decls inside function, do appropriate things;
64 ffecom_end_compstmt ();
65 finish_function (is_nested);
66 if (is_nested) pop_f_function_context ();
71 // fill in external, public, static, &c for decl, and
72 // set DECL_INITIAL to error_mark_node if going to initialize
73 // set is_top_level TRUE only if not at top level and decl
74 // must go in top level (i.e. not within current function decl context)
75 d = start_decl (decl, is_top_level);
76 init = ...; // if have initializer
77 finish_decl (d, init, is_top_level);
88 #include "output.h" /* Must follow tree.h so TREE_CODE is defined! */
91 #include "diagnostic.h"
93 #include "langhooks.h"
94 #include "langhooks-def.h"
96 /* VMS-specific definitions */
99 #define O_RDONLY 0 /* Open arg for Read/Only */
100 #define O_WRONLY 1 /* Open arg for Write/Only */
101 #define read(fd,buf,size) VMS_read (fd,buf,size)
102 #define write(fd,buf,size) VMS_write (fd,buf,size)
103 #define open(fname,mode,prot) VMS_open (fname,mode,prot)
104 #define fopen(fname,mode) VMS_fopen (fname,mode)
105 #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
106 #define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
107 #define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
108 static int VMS_fstat (), VMS_stat ();
109 static char * VMS_strncat ();
110 static int VMS_read ();
111 static int VMS_write ();
112 static int VMS_open ();
113 static FILE * VMS_fopen ();
114 static FILE * VMS_freopen ();
115 static void hack_vms_include_specification ();
116 typedef struct { unsigned :16, :16, :16; } vms_ino_t;
117 #define ino_t vms_ino_t
118 #define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
121 #define FFECOM_DETERMINE_TYPES 1 /* for com.h */
138 /* Externals defined here. */
140 /* Stream for reading from the input file. */
143 /* These definitions parallel those in c-decl.c so that code from that
144 module can be used pretty much as is. Much of these defs aren't
145 otherwise used, i.e. by g77 code per se, except some of them are used
146 to build some of them that are. The ones that are global (i.e. not
147 "static") are those that ste.c and such might use (directly
148 or by using com macros that reference them in their definitions). */
150 tree string_type_node;
152 /* The rest of these are inventions for g77, though there might be
153 similar things in the C front end. As they are found, these
154 inventions should be renamed to be canonical. Note that only
155 the ones currently required to be global are so. */
157 static tree ffecom_tree_fun_type_void;
159 tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
160 tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
161 tree ffecom_integer_one_node; /* " */
162 tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
164 /* _fun_type things are the f2c-specific versions. For -fno-f2c,
165 just use build_function_type and build_pointer_type on the
166 appropriate _tree_type array element. */
168 static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
169 static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
170 static tree ffecom_tree_subr_type;
171 static tree ffecom_tree_ptr_to_subr_type;
172 static tree ffecom_tree_blockdata_type;
174 static tree ffecom_tree_xargc_;
176 ffecomSymbol ffecom_symbol_null_
185 ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
186 ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
188 int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
189 tree ffecom_f2c_integer_type_node;
190 tree ffecom_f2c_ptr_to_integer_type_node;
191 tree ffecom_f2c_address_type_node;
192 tree ffecom_f2c_real_type_node;
193 tree ffecom_f2c_ptr_to_real_type_node;
194 tree ffecom_f2c_doublereal_type_node;
195 tree ffecom_f2c_complex_type_node;
196 tree ffecom_f2c_doublecomplex_type_node;
197 tree ffecom_f2c_longint_type_node;
198 tree ffecom_f2c_logical_type_node;
199 tree ffecom_f2c_flag_type_node;
200 tree ffecom_f2c_ftnlen_type_node;
201 tree ffecom_f2c_ftnlen_zero_node;
202 tree ffecom_f2c_ftnlen_one_node;
203 tree ffecom_f2c_ftnlen_two_node;
204 tree ffecom_f2c_ptr_to_ftnlen_type_node;
205 tree ffecom_f2c_ftnint_type_node;
206 tree ffecom_f2c_ptr_to_ftnint_type_node;
208 /* Simple definitions and enumerations. */
210 #ifndef FFECOM_sizeMAXSTACKITEM
211 #define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
212 larger than this # bytes
213 off stack if possible. */
216 /* For systems that have large enough stacks, they should define
217 this to 0, and here, for ease of use later on, we just undefine
220 #if FFECOM_sizeMAXSTACKITEM == 0
221 #undef FFECOM_sizeMAXSTACKITEM
227 FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */
228 FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */
229 FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */
230 FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */
231 FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */
232 FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */
233 FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */
234 FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */
235 FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */
236 FFECOM_rttypeDOUBLE_, /* C's `double' type. */
237 FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */
238 FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */
239 FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */
240 FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */
244 /* Internal typedefs. */
246 typedef struct _ffecom_concat_list_ ffecomConcatList_;
248 /* Private include files. */
251 /* Internal structure definitions. */
253 struct _ffecom_concat_list_
258 ffetargetCharacterSize minlen;
259 ffetargetCharacterSize maxlen;
262 /* Static functions (internal). */
264 static void ffecom_init_decl_processing PARAMS ((void));
265 static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
266 static tree ffecom_widest_expr_type_ (ffebld list);
267 static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
268 tree dest_size, tree source_tree,
269 ffebld source, bool scalar_arg);
270 static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
271 tree args, tree callee_commons,
273 static tree ffecom_build_f2c_string_ (int i, const char *s);
274 static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
275 bool is_f2c_complex, tree type,
276 tree args, tree dest_tree,
277 ffebld dest, bool *dest_used,
278 tree callee_commons, bool scalar_args, tree hook);
279 static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
280 bool is_f2c_complex, tree type,
281 ffebld left, ffebld right,
282 tree dest_tree, ffebld dest,
283 bool *dest_used, tree callee_commons,
284 bool scalar_args, bool ref, tree hook);
285 static void ffecom_char_args_x_ (tree *xitem, tree *length,
286 ffebld expr, bool with_null);
287 static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
288 static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
289 static ffecomConcatList_
290 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
292 ffetargetCharacterSize max);
293 static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
294 static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
295 ffetargetCharacterSize max);
296 static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
297 ffesymbol member, tree member_type,
298 ffetargetOffset offset);
299 static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
300 static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
301 bool *dest_used, bool assignp, bool widenp);
302 static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
303 ffebld dest, bool *dest_used);
304 static tree ffecom_expr_power_integer_ (ffebld expr);
305 static void ffecom_expr_transform_ (ffebld expr);
306 static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
307 static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
309 static ffeglobal ffecom_finish_global_ (ffeglobal global);
310 static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
311 static tree ffecom_get_appended_identifier_ (char us, const char *text);
312 static tree ffecom_get_external_identifier_ (ffesymbol s);
313 static tree ffecom_get_identifier_ (const char *text);
314 static tree ffecom_gen_sfuncdef_ (ffesymbol s,
317 static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
318 static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
319 static tree ffecom_init_zero_ (tree decl);
320 static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
322 static tree ffecom_intrinsic_len_ (ffebld expr);
323 static void ffecom_let_char_ (tree dest_tree,
325 ffetargetCharacterSize dest_size,
327 static void ffecom_make_gfrt_ (ffecomGfrt ix);
328 static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
329 static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
330 static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
332 static void ffecom_push_dummy_decls_ (ffebld dumlist,
334 static void ffecom_start_progunit_ (void);
335 static ffesymbol ffecom_sym_transform_ (ffesymbol s);
336 static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
337 static void ffecom_transform_common_ (ffesymbol s);
338 static void ffecom_transform_equiv_ (ffestorag st);
339 static tree ffecom_transform_namelist_ (ffesymbol s);
340 static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
342 static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
343 tree *size, tree tree);
344 static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
345 tree dest_tree, ffebld dest,
346 bool *dest_used, tree hook);
347 static tree ffecom_type_localvar_ (ffesymbol s,
350 static tree ffecom_type_namelist_ (void);
351 static tree ffecom_type_vardesc_ (void);
352 static tree ffecom_vardesc_ (ffebld expr);
353 static tree ffecom_vardesc_array_ (ffesymbol s);
354 static tree ffecom_vardesc_dims_ (ffesymbol s);
355 static tree ffecom_convert_narrow_ (tree type, tree expr);
356 static tree ffecom_convert_widen_ (tree type, tree expr);
358 /* These are static functions that parallel those found in the C front
359 end and thus have the same names. */
361 static tree bison_rule_compstmt_ (void);
362 static void bison_rule_pushlevel_ (void);
363 static void delete_block (tree block);
364 static int duplicate_decls (tree newdecl, tree olddecl);
365 static void finish_decl (tree decl, tree init, bool is_top_level);
366 static void finish_function (int nested);
367 static const char *ffe_printable_name (tree decl, int v);
368 static tree lookup_name_current_level (tree name);
369 static struct binding_level *make_binding_level (void);
370 static void pop_f_function_context (void);
371 static void push_f_function_context (void);
372 static void push_parm_decl (tree parm);
373 static tree pushdecl_top_level (tree decl);
374 static int kept_level_p (void);
375 static tree storedecls (tree decls);
376 static void store_parm_decls (int is_main_program);
377 static tree start_decl (tree decl, bool is_top_level);
378 static void start_function (tree name, tree type, int nested, int public);
379 static void ffecom_file_ (const char *name);
380 static void ffecom_close_include_ (FILE *f);
381 static int ffecom_decode_include_option_ (char *spec);
382 static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
385 /* Static objects accessed by functions in this module. */
387 static ffesymbol ffecom_primary_entry_ = NULL;
388 static ffesymbol ffecom_nested_entry_ = NULL;
389 static ffeinfoKind ffecom_primary_entry_kind_;
390 static bool ffecom_primary_entry_is_proc_;
391 static tree ffecom_outer_function_decl_;
392 static tree ffecom_previous_function_decl_;
393 static tree ffecom_which_entrypoint_decl_;
394 static tree ffecom_float_zero_ = NULL_TREE;
395 static tree ffecom_float_half_ = NULL_TREE;
396 static tree ffecom_double_zero_ = NULL_TREE;
397 static tree ffecom_double_half_ = NULL_TREE;
398 static tree ffecom_func_result_;/* For functions. */
399 static tree ffecom_func_length_;/* For CHARACTER fns. */
400 static ffebld ffecom_list_blockdata_;
401 static ffebld ffecom_list_common_;
402 static ffebld ffecom_master_arglist_;
403 static ffeinfoBasictype ffecom_master_bt_;
404 static ffeinfoKindtype ffecom_master_kt_;
405 static ffetargetCharacterSize ffecom_master_size_;
406 static int ffecom_num_fns_ = 0;
407 static int ffecom_num_entrypoints_ = 0;
408 static bool ffecom_is_altreturning_ = FALSE;
409 static tree ffecom_multi_type_node_;
410 static tree ffecom_multi_retval_;
412 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
413 static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
414 static bool ffecom_doing_entry_ = FALSE;
415 static bool ffecom_transform_only_dummies_ = FALSE;
416 static int ffecom_typesize_pointer_;
417 static int ffecom_typesize_integer1_;
419 /* Holds pointer-to-function expressions. */
421 static tree ffecom_gfrt_[FFECOM_gfrt]
424 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NULL_TREE,
425 #include "com-rt.def"
429 /* Holds the external names of the functions. */
431 static const char *const ffecom_gfrt_name_[FFECOM_gfrt]
434 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NAME,
435 #include "com-rt.def"
439 /* Whether the function returns. */
441 static const bool ffecom_gfrt_volatile_[FFECOM_gfrt]
444 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) VOLATILE,
445 #include "com-rt.def"
449 /* Whether the function returns type complex. */
451 static const bool ffecom_gfrt_complex_[FFECOM_gfrt]
454 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) COMPLEX,
455 #include "com-rt.def"
459 /* Whether the function is const
460 (i.e., has no side effects and only depends on its arguments). */
462 static const bool ffecom_gfrt_const_[FFECOM_gfrt]
465 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) CONST,
466 #include "com-rt.def"
470 /* Type code for the function return value. */
472 static const ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
475 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) TYPE,
476 #include "com-rt.def"
480 /* String of codes for the function's arguments. */
482 static const char *const ffecom_gfrt_argstring_[FFECOM_gfrt]
485 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) ARGS,
486 #include "com-rt.def"
490 /* Internal macros. */
492 /* We let tm.h override the types used here, to handle trivial differences
493 such as the choice of unsigned int or long unsigned int for size_t.
494 When machines start needing nontrivial differences in the size type,
495 it would be best to do something here to figure out automatically
496 from other information what type to use. */
499 #define SIZE_TYPE "long unsigned int"
502 #define ffecom_concat_list_count_(catlist) ((catlist).count)
503 #define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
504 #define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
505 #define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
507 #define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
508 #define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
510 /* For each binding contour we allocate a binding_level structure
511 * which records the names defined in that contour.
514 * 1) one for each function definition,
515 * where internal declarations of the parameters appear.
517 * The current meaning of a name can be found by searching the levels from
518 * the current one out to the global one.
521 /* Note that the information in the `names' component of the global contour
522 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
526 /* A chain of _DECL nodes for all variables, constants, functions,
527 and typedef types. These are in the reverse of the order supplied.
531 /* For each level (except not the global one),
532 a chain of BLOCK nodes for all the levels
533 that were entered and exited one level down. */
536 /* The BLOCK node for this level, if one has been preallocated.
537 If 0, the BLOCK is allocated (if needed) when the level is popped. */
540 /* The binding level which this one is contained in (inherits from). */
541 struct binding_level *level_chain;
543 /* 0: no ffecom_prepare_* functions called at this level yet;
544 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
545 2: ffecom_prepare_end called. */
549 #define NULL_BINDING_LEVEL (struct binding_level *) NULL
551 /* The binding level currently in effect. */
553 static struct binding_level *current_binding_level;
555 /* A chain of binding_level structures awaiting reuse. */
557 static struct binding_level *free_binding_level;
559 /* The outermost binding level, for names of file scope.
560 This is created when the compiler is started and exists
561 through the entire run. */
563 static struct binding_level *global_binding_level;
565 /* Binding level structures are initialized by copying this one. */
567 static const struct binding_level clear_binding_level
569 {NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
571 /* Language-dependent contents of an identifier. */
573 struct lang_identifier
575 struct tree_identifier ignore;
576 tree global_value, local_value, label_value;
580 /* Macros for access to language-specific slots in an identifier. */
581 /* Each of these slots contains a DECL node or null. */
583 /* This represents the value which the identifier has in the
584 file-scope namespace. */
585 #define IDENTIFIER_GLOBAL_VALUE(NODE) \
586 (((struct lang_identifier *)(NODE))->global_value)
587 /* This represents the value which the identifier has in the current
589 #define IDENTIFIER_LOCAL_VALUE(NODE) \
590 (((struct lang_identifier *)(NODE))->local_value)
591 /* This represents the value which the identifier has as a label in
592 the current label scope. */
593 #define IDENTIFIER_LABEL_VALUE(NODE) \
594 (((struct lang_identifier *)(NODE))->label_value)
595 /* This is nonzero if the identifier was "made up" by g77 code. */
596 #define IDENTIFIER_INVENTED(NODE) \
597 (((struct lang_identifier *)(NODE))->invented)
599 /* In identifiers, C uses the following fields in a special way:
600 TREE_PUBLIC to record that there was a previous local extern decl.
601 TREE_USED to record that such a decl was used.
602 TREE_ADDRESSABLE to record that the address of such a decl was used. */
604 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
605 that have names. Here so we can clear out their names' definitions
606 at the end of the function. */
608 static tree named_labels;
610 /* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
612 static tree shadowed_labels;
614 /* Return the subscript expression, modified to do range-checking.
616 `array' is the array to be checked against.
617 `element' is the subscript expression to check.
618 `dim' is the dimension number (starting at 0).
619 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
623 ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
624 const char *array_name)
626 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
627 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
632 if (element == error_mark_node)
635 if (TREE_TYPE (low) != TREE_TYPE (element))
637 if (TYPE_PRECISION (TREE_TYPE (low))
638 > TYPE_PRECISION (TREE_TYPE (element)))
639 element = convert (TREE_TYPE (low), element);
642 low = convert (TREE_TYPE (element), low);
644 high = convert (TREE_TYPE (element), high);
648 element = ffecom_save_tree (element);
651 /* Special handling for substring range checks. Fortran allows the
652 end subscript < begin subscript, which means that expressions like
653 string(1:0) are valid (and yield a null string). In view of this,
654 enforce two simpler conditions:
655 1) element<=high for end-substring;
656 2) element>=low for start-substring.
657 Run-time character movement will enforce remaining conditions.
659 More complicated checks would be better, but present structure only
660 provides one index element at a time, so it is not possible to
661 enforce a check of both i and j in string(i:j). If it were, the
662 complete set of rules would read,
663 if ( ((j<i) && ((low<=i<=high) || (low<=j<=high))) ||
664 ((low<=i<=high) && (low<=j<=high)) )
670 cond = ffecom_2 (LE_EXPR, integer_type_node, element, high);
672 cond = ffecom_2 (LE_EXPR, integer_type_node, low, element);
676 /* Array reference substring range checking. */
678 cond = ffecom_2 (LE_EXPR, integer_type_node,
683 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
685 ffecom_2 (LE_EXPR, integer_type_node,
703 var = concat (array_name, "[", (dim ? "end" : "start"),
704 "-substring]", NULL);
705 len = strlen (var) + 1;
706 arg1 = build_string (len, var);
711 len = strlen (array_name) + 1;
712 arg1 = build_string (len, array_name);
716 var = xmalloc (strlen (array_name) + 40);
717 sprintf (var, "%s[subscript-%d-of-%d]",
719 dim + 1, total_dims);
720 len = strlen (var) + 1;
721 arg1 = build_string (len, var);
727 = build_type_variant (build_array_type (char_type_node,
731 build_int_2 (len, 0))),
733 TREE_CONSTANT (arg1) = 1;
734 TREE_STATIC (arg1) = 1;
735 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
738 /* s_rnge adds one to the element to print it, so bias against
739 that -- want to print a faithful *subscript* value. */
740 arg2 = convert (ffecom_f2c_ftnint_type_node,
741 ffecom_2 (MINUS_EXPR,
744 convert (TREE_TYPE (element),
747 proc = concat (input_filename, "/",
748 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
750 len = strlen (proc) + 1;
751 arg3 = build_string (len, proc);
756 = build_type_variant (build_array_type (char_type_node,
760 build_int_2 (len, 0))),
762 TREE_CONSTANT (arg3) = 1;
763 TREE_STATIC (arg3) = 1;
764 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
767 arg4 = convert (ffecom_f2c_ftnint_type_node,
768 build_int_2 (lineno, 0));
770 arg1 = build_tree_list (NULL_TREE, arg1);
771 arg2 = build_tree_list (NULL_TREE, arg2);
772 arg3 = build_tree_list (NULL_TREE, arg3);
773 arg4 = build_tree_list (NULL_TREE, arg4);
774 TREE_CHAIN (arg3) = arg4;
775 TREE_CHAIN (arg2) = arg3;
776 TREE_CHAIN (arg1) = arg2;
780 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
782 TREE_SIDE_EFFECTS (die) = 1;
784 element = ffecom_3 (COND_EXPR,
793 /* Return the computed element of an array reference.
795 `item' is NULL_TREE, or the transformed pointer to the array.
796 `expr' is the original opARRAYREF expression, which is transformed
797 if `item' is NULL_TREE.
798 `want_ptr' is non-zero if a pointer to the element, instead of
799 the element itself, is to be returned. */
802 ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
804 ffebld dims[FFECOM_dimensionsMAX];
807 int flatten = ffe_is_flatten_arrays ();
813 const char *array_name;
817 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
818 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
820 array_name = "[expr?]";
822 /* Build up ARRAY_REFs in reverse order (since we're column major
823 here in Fortran land). */
825 for (i = 0, list = ffebld_right (expr);
827 ++i, list = ffebld_trail (list))
829 dims[i] = ffebld_head (list);
830 type = ffeinfo_type (ffebld_basictype (dims[i]),
831 ffebld_kindtype (dims[i]));
833 && ffecom_typesize_pointer_ > ffecom_typesize_integer1_
834 && ffetype_size (type) > ffecom_typesize_integer1_)
835 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
836 pointers and 32-bit integers. Do the full 64-bit pointer
837 arithmetic, for codes using arrays for nonstandard heap-like
844 need_ptr = want_ptr || flatten;
849 item = ffecom_ptr_to_expr (ffebld_left (expr));
851 item = ffecom_expr (ffebld_left (expr));
853 if (item == error_mark_node)
856 if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
857 && ! mark_addressable (item))
858 return error_mark_node;
861 if (item == error_mark_node)
868 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
870 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
872 min = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
873 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
874 if (flag_bounds_check)
875 element = ffecom_subscript_check_ (array, element, i, total_dims,
877 if (element == error_mark_node)
880 /* Widen integral arithmetic as desired while preserving
882 tree_type = TREE_TYPE (element);
883 tree_type_x = tree_type;
885 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
886 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
887 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
889 if (TREE_TYPE (min) != tree_type_x)
890 min = convert (tree_type_x, min);
891 if (TREE_TYPE (element) != tree_type_x)
892 element = convert (tree_type_x, element);
894 item = ffecom_2 (PLUS_EXPR,
895 build_pointer_type (TREE_TYPE (array)),
897 size_binop (MULT_EXPR,
898 size_in_bytes (TREE_TYPE (array)),
900 fold (build (MINUS_EXPR,
906 item = ffecom_1 (INDIRECT_REF,
907 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
917 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
919 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
920 if (flag_bounds_check)
921 element = ffecom_subscript_check_ (array, element, i, total_dims,
923 if (element == error_mark_node)
926 /* Widen integral arithmetic as desired while preserving
928 tree_type = TREE_TYPE (element);
929 tree_type_x = tree_type;
931 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
932 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
933 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
935 element = convert (tree_type_x, element);
937 item = ffecom_2 (ARRAY_REF,
938 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
947 /* This is like gcc's stabilize_reference -- in fact, most of the code
948 comes from that -- but it handles the situation where the reference
949 is going to have its subparts picked at, and it shouldn't change
950 (or trigger extra invocations of functions in the subtrees) due to
951 this. save_expr is a bit overzealous, because we don't need the
952 entire thing calculated and saved like a temp. So, for DECLs, no
953 change is needed, because these are stable aggregates, and ARRAY_REF
954 and such might well be stable too, but for things like calculations,
955 we do need to calculate a snapshot of a value before picking at it. */
958 ffecom_stabilize_aggregate_ (tree ref)
961 enum tree_code code = TREE_CODE (ref);
968 /* No action is needed in this case. */
978 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
982 result = build_nt (INDIRECT_REF,
983 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
987 result = build_nt (COMPONENT_REF,
988 stabilize_reference (TREE_OPERAND (ref, 0)),
989 TREE_OPERAND (ref, 1));
993 result = build_nt (BIT_FIELD_REF,
994 stabilize_reference (TREE_OPERAND (ref, 0)),
995 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
996 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
1000 result = build_nt (ARRAY_REF,
1001 stabilize_reference (TREE_OPERAND (ref, 0)),
1002 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1006 result = build_nt (COMPOUND_EXPR,
1007 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1008 stabilize_reference (TREE_OPERAND (ref, 1)));
1016 return save_expr (ref);
1019 return error_mark_node;
1022 TREE_TYPE (result) = TREE_TYPE (ref);
1023 TREE_READONLY (result) = TREE_READONLY (ref);
1024 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1025 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
1030 /* A rip-off of gcc's convert.c convert_to_complex function,
1031 reworked to handle complex implemented as C structures
1032 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1035 ffecom_convert_to_complex_ (tree type, tree expr)
1037 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1040 assert (TREE_CODE (type) == RECORD_TYPE);
1042 subtype = TREE_TYPE (TYPE_FIELDS (type));
1044 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1046 expr = convert (subtype, expr);
1047 return ffecom_2 (COMPLEX_EXPR, type, expr,
1048 convert (subtype, integer_zero_node));
1051 if (form == RECORD_TYPE)
1053 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1054 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1058 expr = save_expr (expr);
1059 return ffecom_2 (COMPLEX_EXPR,
1062 ffecom_1 (REALPART_EXPR,
1063 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1066 ffecom_1 (IMAGPART_EXPR,
1067 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1072 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1073 error ("pointer value used where a complex was expected");
1075 error ("aggregate value used where a complex was expected");
1077 return ffecom_2 (COMPLEX_EXPR, type,
1078 convert (subtype, integer_zero_node),
1079 convert (subtype, integer_zero_node));
1082 /* Like gcc's convert(), but crashes if widening might happen. */
1085 ffecom_convert_narrow_ (type, expr)
1088 register tree e = expr;
1089 register enum tree_code code = TREE_CODE (type);
1091 if (type == TREE_TYPE (e)
1092 || TREE_CODE (e) == ERROR_MARK)
1094 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1095 return fold (build1 (NOP_EXPR, type, e));
1096 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1097 || code == ERROR_MARK)
1098 return error_mark_node;
1099 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1101 assert ("void value not ignored as it ought to be" == NULL);
1102 return error_mark_node;
1104 assert (code != VOID_TYPE);
1105 if ((code != RECORD_TYPE)
1106 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1107 assert ("converting COMPLEX to REAL" == NULL);
1108 assert (code != ENUMERAL_TYPE);
1109 if (code == INTEGER_TYPE)
1111 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1112 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
1113 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1114 && (TYPE_PRECISION (type)
1115 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1116 return fold (convert_to_integer (type, e));
1118 if (code == POINTER_TYPE)
1120 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1121 return fold (convert_to_pointer (type, e));
1123 if (code == REAL_TYPE)
1125 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1126 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
1127 return fold (convert_to_real (type, e));
1129 if (code == COMPLEX_TYPE)
1131 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1132 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1133 return fold (convert_to_complex (type, e));
1135 if (code == RECORD_TYPE)
1137 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1138 /* Check that at least the first field name agrees. */
1139 assert (DECL_NAME (TYPE_FIELDS (type))
1140 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1141 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1142 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1143 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1144 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1146 return fold (ffecom_convert_to_complex_ (type, e));
1149 assert ("conversion to non-scalar type requested" == NULL);
1150 return error_mark_node;
1153 /* Like gcc's convert(), but crashes if narrowing might happen. */
1156 ffecom_convert_widen_ (type, expr)
1159 register tree e = expr;
1160 register enum tree_code code = TREE_CODE (type);
1162 if (type == TREE_TYPE (e)
1163 || TREE_CODE (e) == ERROR_MARK)
1165 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1166 return fold (build1 (NOP_EXPR, type, e));
1167 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1168 || code == ERROR_MARK)
1169 return error_mark_node;
1170 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1172 assert ("void value not ignored as it ought to be" == NULL);
1173 return error_mark_node;
1175 assert (code != VOID_TYPE);
1176 if ((code != RECORD_TYPE)
1177 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1178 assert ("narrowing COMPLEX to REAL" == NULL);
1179 assert (code != ENUMERAL_TYPE);
1180 if (code == INTEGER_TYPE)
1182 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1183 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1184 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1185 && (TYPE_PRECISION (type)
1186 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1187 return fold (convert_to_integer (type, e));
1189 if (code == POINTER_TYPE)
1191 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1192 return fold (convert_to_pointer (type, e));
1194 if (code == REAL_TYPE)
1196 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1197 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1198 return fold (convert_to_real (type, e));
1200 if (code == COMPLEX_TYPE)
1202 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1203 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1204 return fold (convert_to_complex (type, e));
1206 if (code == RECORD_TYPE)
1208 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1209 /* Check that at least the first field name agrees. */
1210 assert (DECL_NAME (TYPE_FIELDS (type))
1211 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1212 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1213 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1214 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1215 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1217 return fold (ffecom_convert_to_complex_ (type, e));
1220 assert ("conversion to non-scalar type requested" == NULL);
1221 return error_mark_node;
1224 /* Handles making a COMPLEX type, either the standard
1225 (but buggy?) gbe way, or the safer (but less elegant?)
1229 ffecom_make_complex_type_ (tree subtype)
1235 if (ffe_is_emulate_complex ())
1237 type = make_node (RECORD_TYPE);
1238 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1239 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1240 TYPE_FIELDS (type) = realfield;
1245 type = make_node (COMPLEX_TYPE);
1246 TREE_TYPE (type) = subtype;
1253 /* Chooses either the gbe or the f2c way to build a
1254 complex constant. */
1257 ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1261 if (ffe_is_emulate_complex ())
1263 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1264 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1265 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
1269 bothparts = build_complex (type, realpart, imagpart);
1276 ffecom_arglist_expr_ (const char *c, ffebld expr)
1279 tree *plist = &list;
1280 tree trail = NULL_TREE; /* Append char length args here. */
1281 tree *ptrail = &trail;
1286 tree wanted = NULL_TREE;
1287 static const char zed[] = "0";
1292 while (expr != NULL)
1315 wanted = ffecom_f2c_complex_type_node;
1319 wanted = ffecom_f2c_doublereal_type_node;
1323 wanted = ffecom_f2c_doublecomplex_type_node;
1327 wanted = ffecom_f2c_real_type_node;
1331 wanted = ffecom_f2c_integer_type_node;
1335 wanted = ffecom_f2c_longint_type_node;
1339 assert ("bad argstring code" == NULL);
1345 exprh = ffebld_head (expr);
1349 if ((wanted == NULL_TREE)
1352 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1353 [ffeinfo_kindtype (ffebld_info (exprh))])
1354 == TYPE_MODE (wanted))))
1356 = build_tree_list (NULL_TREE,
1357 ffecom_arg_ptr_to_expr (exprh,
1361 item = ffecom_arg_expr (exprh, &length);
1362 item = ffecom_convert_widen_ (wanted, item);
1365 item = ffecom_1 (ADDR_EXPR,
1366 build_pointer_type (TREE_TYPE (item)),
1370 = build_tree_list (NULL_TREE,
1374 plist = &TREE_CHAIN (*plist);
1375 expr = ffebld_trail (expr);
1376 if (length != NULL_TREE)
1378 *ptrail = build_tree_list (NULL_TREE, length);
1379 ptrail = &TREE_CHAIN (*ptrail);
1383 /* We've run out of args in the call; if the implementation expects
1384 more, supply null pointers for them, which the implementation can
1385 check to see if an arg was omitted. */
1387 while (*c != '\0' && *c != '0')
1392 assert ("missing arg to run-time routine!" == NULL);
1407 assert ("bad arg string code" == NULL);
1411 = build_tree_list (NULL_TREE,
1413 plist = &TREE_CHAIN (*plist);
1422 ffecom_widest_expr_type_ (ffebld list)
1425 ffebld widest = NULL;
1427 ffetype widest_type = NULL;
1430 for (; list != NULL; list = ffebld_trail (list))
1432 item = ffebld_head (list);
1435 if ((widest != NULL)
1436 && (ffeinfo_basictype (ffebld_info (item))
1437 != ffeinfo_basictype (ffebld_info (widest))))
1439 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1440 ffeinfo_kindtype (ffebld_info (item)));
1441 if ((widest == FFEINFO_kindtypeNONE)
1442 || (ffetype_size (type)
1443 > ffetype_size (widest_type)))
1450 assert (widest != NULL);
1451 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1452 [ffeinfo_kindtype (ffebld_info (widest))];
1453 assert (t != NULL_TREE);
1457 /* Check whether a partial overlap between two expressions is possible.
1459 Can *starting* to write a portion of expr1 change the value
1460 computed (perhaps already, *partially*) by expr2?
1462 Currently, this is a concern only for a COMPLEX expr1. But if it
1463 isn't in COMMON or local EQUIVALENCE, since we don't support
1464 aliasing of arguments, it isn't a concern. */
1467 ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2 ATTRIBUTE_UNUSED)
1472 switch (ffebld_op (expr1))
1474 case FFEBLD_opSYMTER:
1475 sym = ffebld_symter (expr1);
1478 case FFEBLD_opARRAYREF:
1479 if (ffebld_op (ffebld_left (expr1)) != FFEBLD_opSYMTER)
1481 sym = ffebld_symter (ffebld_left (expr1));
1488 if (ffesymbol_where (sym) != FFEINFO_whereCOMMON
1489 && (ffesymbol_where (sym) != FFEINFO_whereLOCAL
1490 || ! (st = ffesymbol_storage (sym))
1491 || ! ffestorag_parent (st)))
1494 /* It's in COMMON or local EQUIVALENCE. */
1499 /* Check whether dest and source might overlap. ffebld versions of these
1500 might or might not be passed, will be NULL if not.
1502 The test is really whether source_tree is modifiable and, if modified,
1503 might overlap destination such that the value(s) in the destination might
1504 change before it is finally modified. dest_* are the canonized
1505 destination itself. */
1508 ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1509 tree source_tree, ffebld source UNUSED,
1517 if (source_tree == NULL_TREE)
1520 switch (TREE_CODE (source_tree))
1523 case IDENTIFIER_NODE:
1534 case TRUNC_DIV_EXPR:
1536 case FLOOR_DIV_EXPR:
1537 case ROUND_DIV_EXPR:
1538 case TRUNC_MOD_EXPR:
1540 case FLOOR_MOD_EXPR:
1541 case ROUND_MOD_EXPR:
1543 case EXACT_DIV_EXPR:
1544 case FIX_TRUNC_EXPR:
1546 case FIX_FLOOR_EXPR:
1547 case FIX_ROUND_EXPR:
1561 case BIT_ANDTC_EXPR:
1563 case TRUTH_ANDIF_EXPR:
1564 case TRUTH_ORIF_EXPR:
1565 case TRUTH_AND_EXPR:
1567 case TRUTH_XOR_EXPR:
1568 case TRUTH_NOT_EXPR:
1584 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1585 TREE_OPERAND (source_tree, 1), NULL,
1589 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1590 TREE_OPERAND (source_tree, 0), NULL,
1595 case NON_LVALUE_EXPR:
1597 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1600 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1602 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1607 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1608 TREE_OPERAND (source_tree, 1), NULL,
1610 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1611 TREE_OPERAND (source_tree, 2), NULL,
1616 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1618 TREE_OPERAND (source_tree, 0));
1622 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1625 source_decl = source_tree;
1626 source_offset = bitsize_zero_node;
1627 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1631 case REFERENCE_EXPR:
1632 case PREDECREMENT_EXPR:
1633 case PREINCREMENT_EXPR:
1634 case POSTDECREMENT_EXPR:
1635 case POSTINCREMENT_EXPR:
1643 /* Come here when source_decl, source_offset, and source_size filled
1644 in appropriately. */
1646 if (source_decl == NULL_TREE)
1647 return FALSE; /* No decl involved, so no overlap. */
1649 if (source_decl != dest_decl)
1650 return FALSE; /* Different decl, no overlap. */
1652 if (TREE_CODE (dest_size) == ERROR_MARK)
1653 return TRUE; /* Assignment into entire assumed-size
1654 array? Shouldn't happen.... */
1656 t = ffecom_2 (LE_EXPR, integer_type_node,
1657 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1659 convert (TREE_TYPE (dest_offset),
1661 convert (TREE_TYPE (dest_offset),
1664 if (integer_onep (t))
1665 return FALSE; /* Destination precedes source. */
1668 || (source_size == NULL_TREE)
1669 || (TREE_CODE (source_size) == ERROR_MARK)
1670 || integer_zerop (source_size))
1671 return TRUE; /* No way to tell if dest follows source. */
1673 t = ffecom_2 (LE_EXPR, integer_type_node,
1674 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1676 convert (TREE_TYPE (source_offset),
1678 convert (TREE_TYPE (source_offset),
1681 if (integer_onep (t))
1682 return FALSE; /* Destination follows source. */
1684 return TRUE; /* Destination and source overlap. */
1687 /* Check whether dest might overlap any of a list of arguments or is
1688 in a COMMON area the callee might know about (and thus modify). */
1691 ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
1692 tree args, tree callee_commons,
1700 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1703 if (dest_decl == NULL_TREE)
1704 return FALSE; /* Seems unlikely! */
1706 /* If the decl cannot be determined reliably, or if its in COMMON
1707 and the callee isn't known to not futz with COMMON via other
1708 means, overlap might happen. */
1710 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1711 || ((callee_commons != NULL_TREE)
1712 && TREE_PUBLIC (dest_decl)))
1715 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1717 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1718 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1719 arg, NULL, scalar_args))
1726 /* Build a string for a variable name as used by NAMELIST. This means that
1727 if we're using the f2c library, we build an uppercase string, since
1731 ffecom_build_f2c_string_ (int i, const char *s)
1733 if (!ffe_is_f2c_library ())
1734 return build_string (i, s);
1743 if (((size_t) i) > ARRAY_SIZE (space))
1744 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1748 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
1752 t = build_string (i, tmp);
1754 if (((size_t) i) > ARRAY_SIZE (space))
1755 malloc_kill_ks (malloc_pool_image (), tmp, i);
1761 /* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1762 type to just get whatever the function returns), handling the
1763 f2c value-returning convention, if required, by prepending
1764 to the arglist a pointer to a temporary to receive the return value. */
1767 ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1768 tree type, tree args, tree dest_tree,
1769 ffebld dest, bool *dest_used, tree callee_commons,
1770 bool scalar_args, tree hook)
1775 if (dest_used != NULL)
1780 if ((dest_used == NULL)
1782 || (ffeinfo_basictype (ffebld_info (dest))
1783 != FFEINFO_basictypeCOMPLEX)
1784 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1785 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1786 || ffecom_args_overlapping_ (dest_tree, dest, args,
1791 tempvar = ffecom_make_tempvar (ffecom_tree_type
1792 [FFEINFO_basictypeCOMPLEX][kt],
1793 FFETARGET_charactersizeNONE,
1803 tempvar = dest_tree;
1808 = build_tree_list (NULL_TREE,
1809 ffecom_1 (ADDR_EXPR,
1810 build_pointer_type (TREE_TYPE (tempvar)),
1812 TREE_CHAIN (item) = args;
1814 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1817 if (tempvar != dest_tree)
1818 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1821 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1824 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1825 item = ffecom_convert_narrow_ (type, item);
1830 /* Given two arguments, transform them and make a call to the given
1831 function via ffecom_call_. */
1834 ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1835 tree type, ffebld left, ffebld right,
1836 tree dest_tree, ffebld dest, bool *dest_used,
1837 tree callee_commons, bool scalar_args, bool ref, tree hook)
1846 /* Pass arguments by reference. */
1847 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1848 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
1852 /* Pass arguments by value. */
1853 left_tree = ffecom_arg_expr (left, &left_length);
1854 right_tree = ffecom_arg_expr (right, &right_length);
1858 left_tree = build_tree_list (NULL_TREE, left_tree);
1859 right_tree = build_tree_list (NULL_TREE, right_tree);
1860 TREE_CHAIN (left_tree) = right_tree;
1862 if (left_length != NULL_TREE)
1864 left_length = build_tree_list (NULL_TREE, left_length);
1865 TREE_CHAIN (right_tree) = left_length;
1868 if (right_length != NULL_TREE)
1870 right_length = build_tree_list (NULL_TREE, right_length);
1871 if (left_length != NULL_TREE)
1872 TREE_CHAIN (left_length) = right_length;
1874 TREE_CHAIN (right_tree) = right_length;
1877 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1878 dest_tree, dest, dest_used, callee_commons,
1882 /* Return ptr/length args for char subexpression
1884 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1885 subexpressions by constructing the appropriate trees for the ptr-to-
1886 character-text and length-of-character-text arguments in a calling
1889 Note that if with_null is TRUE, and the expression is an opCONTER,
1890 a null byte is appended to the string. */
1893 ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
1897 ffetargetCharacter1 val;
1898 ffetargetCharacterSize newlen;
1900 switch (ffebld_op (expr))
1902 case FFEBLD_opCONTER:
1903 val = ffebld_constant_character1 (ffebld_conter (expr));
1904 newlen = ffetarget_length_character1 (val);
1907 /* Begin FFETARGET-NULL-KLUDGE. */
1911 *length = build_int_2 (newlen, 0);
1912 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1913 high = build_int_2 (newlen, 0);
1914 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
1915 item = build_string (newlen,
1916 ffetarget_text_character1 (val));
1917 /* End FFETARGET-NULL-KLUDGE. */
1919 = build_type_variant
1923 (ffecom_f2c_ftnlen_type_node,
1924 ffecom_f2c_ftnlen_one_node,
1927 TREE_CONSTANT (item) = 1;
1928 TREE_STATIC (item) = 1;
1929 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
1933 case FFEBLD_opSYMTER:
1935 ffesymbol s = ffebld_symter (expr);
1937 item = ffesymbol_hook (s).decl_tree;
1938 if (item == NULL_TREE)
1940 s = ffecom_sym_transform_ (s);
1941 item = ffesymbol_hook (s).decl_tree;
1943 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
1945 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
1946 *length = ffesymbol_hook (s).length_tree;
1949 *length = build_int_2 (ffesymbol_size (s), 0);
1950 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1953 else if (item == error_mark_node)
1954 *length = error_mark_node;
1956 /* FFEINFO_kindFUNCTION. */
1957 *length = NULL_TREE;
1958 if (!ffesymbol_hook (s).addr
1959 && (item != error_mark_node))
1960 item = ffecom_1 (ADDR_EXPR,
1961 build_pointer_type (TREE_TYPE (item)),
1966 case FFEBLD_opARRAYREF:
1968 ffecom_char_args_ (&item, length, ffebld_left (expr));
1970 if (item == error_mark_node || *length == error_mark_node)
1972 item = *length = error_mark_node;
1976 item = ffecom_arrayref_ (item, expr, 1);
1980 case FFEBLD_opSUBSTR:
1984 ffebld thing = ffebld_right (expr);
1987 const char *char_name;
1991 assert (ffebld_op (thing) == FFEBLD_opITEM);
1992 start = ffebld_head (thing);
1993 thing = ffebld_trail (thing);
1994 assert (ffebld_trail (thing) == NULL);
1995 end = ffebld_head (thing);
1997 /* Determine name for pretty-printing range-check errors. */
1998 for (left_symter = ffebld_left (expr);
1999 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
2000 left_symter = ffebld_left (left_symter))
2002 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2003 char_name = ffesymbol_text (ffebld_symter (left_symter));
2005 char_name = "[expr?]";
2007 ffecom_char_args_ (&item, length, ffebld_left (expr));
2009 if (item == error_mark_node || *length == error_mark_node)
2011 item = *length = error_mark_node;
2015 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2017 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2025 end_tree = ffecom_expr (end);
2026 if (flag_bounds_check)
2027 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2029 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2032 if (end_tree == error_mark_node)
2034 item = *length = error_mark_node;
2043 start_tree = ffecom_expr (start);
2044 if (flag_bounds_check)
2045 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2047 start_tree = convert (ffecom_f2c_ftnlen_type_node,
2050 if (start_tree == error_mark_node)
2052 item = *length = error_mark_node;
2056 start_tree = ffecom_save_tree (start_tree);
2058 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2060 ffecom_2 (MINUS_EXPR,
2061 TREE_TYPE (start_tree),
2063 ffecom_f2c_ftnlen_one_node));
2067 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2068 ffecom_f2c_ftnlen_one_node,
2069 ffecom_2 (MINUS_EXPR,
2070 ffecom_f2c_ftnlen_type_node,
2076 end_tree = ffecom_expr (end);
2077 if (flag_bounds_check)
2078 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2080 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2083 if (end_tree == error_mark_node)
2085 item = *length = error_mark_node;
2089 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2090 ffecom_f2c_ftnlen_one_node,
2091 ffecom_2 (MINUS_EXPR,
2092 ffecom_f2c_ftnlen_type_node,
2093 end_tree, start_tree));
2099 case FFEBLD_opFUNCREF:
2101 ffesymbol s = ffebld_symter (ffebld_left (expr));
2104 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2107 if (size == FFETARGET_charactersizeNONE)
2108 /* ~~Kludge alert! This should someday be fixed. */
2111 *length = build_int_2 (size, 0);
2112 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2114 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2115 == FFEINFO_whereINTRINSIC)
2119 /* Invocation of an intrinsic returning CHARACTER*1. */
2120 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2124 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2125 assert (ix != FFECOM_gfrt);
2126 item = ffecom_gfrt_tree_ (ix);
2131 item = ffesymbol_hook (s).decl_tree;
2132 if (item == NULL_TREE)
2134 s = ffecom_sym_transform_ (s);
2135 item = ffesymbol_hook (s).decl_tree;
2137 if (item == error_mark_node)
2139 item = *length = error_mark_node;
2143 if (!ffesymbol_hook (s).addr)
2144 item = ffecom_1_fn (item);
2148 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
2150 tempvar = ffebld_nonter_hook (expr);
2153 tempvar = ffecom_1 (ADDR_EXPR,
2154 build_pointer_type (TREE_TYPE (tempvar)),
2157 args = build_tree_list (NULL_TREE, tempvar);
2159 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */
2160 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
2163 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
2164 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
2166 TREE_CHAIN (TREE_CHAIN (args))
2167 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
2168 ffebld_right (expr));
2172 TREE_CHAIN (TREE_CHAIN (args))
2173 = ffecom_list_ptr_to_expr (ffebld_right (expr));
2177 item = ffecom_3s (CALL_EXPR,
2178 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
2179 item, args, NULL_TREE);
2180 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
2185 case FFEBLD_opCONVERT:
2187 ffecom_char_args_ (&item, length, ffebld_left (expr));
2189 if (item == error_mark_node || *length == error_mark_node)
2191 item = *length = error_mark_node;
2195 if ((ffebld_size_known (ffebld_left (expr))
2196 == FFETARGET_charactersizeNONE)
2197 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
2198 { /* Possible blank-padding needed, copy into
2205 tempvar = ffecom_make_tempvar (char_type_node,
2206 ffebld_size (expr), -1);
2208 tempvar = ffebld_nonter_hook (expr);
2211 tempvar = ffecom_1 (ADDR_EXPR,
2212 build_pointer_type (TREE_TYPE (tempvar)),
2215 newlen = build_int_2 (ffebld_size (expr), 0);
2216 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2218 args = build_tree_list (NULL_TREE, tempvar);
2219 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2220 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2221 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2222 = build_tree_list (NULL_TREE, *length);
2224 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
2225 TREE_SIDE_EFFECTS (item) = 1;
2226 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2231 { /* Just truncate the length. */
2232 *length = build_int_2 (ffebld_size (expr), 0);
2233 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2238 assert ("bad op for single char arg expr" == NULL);
2246 /* Check the size of the type to be sure it doesn't overflow the
2247 "portable" capacities of the compiler back end. `dummy' types
2248 can generally overflow the normal sizes as long as the computations
2249 themselves don't overflow. A particular target of the back end
2250 must still enforce its size requirements, though, and the back
2251 end takes care of this in stor-layout.c. */
2254 ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2256 if (TREE_CODE (type) == ERROR_MARK)
2259 if (TYPE_SIZE (type) == NULL_TREE)
2262 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2265 /* An array is too large if size is negative or the type_size overflows
2266 or its "upper half" is larger than 3 (which would make the signed
2267 byte size and offset computations overflow). */
2269 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
2270 || (!dummy && (TREE_INT_CST_HIGH (TYPE_SIZE (type)) > 3
2271 || TREE_OVERFLOW (TYPE_SIZE (type)))))
2273 ffebad_start (FFEBAD_ARRAY_LARGE);
2274 ffebad_string (ffesymbol_text (s));
2275 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2278 return error_mark_node;
2284 /* Builds a length argument (PARM_DECL). Also wraps type in an array type
2285 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2286 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2289 ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2291 ffetargetCharacterSize sz = ffesymbol_size (s);
2296 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2297 tlen = NULL_TREE; /* A statement function, no length passed. */
2300 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2301 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
2302 ffesymbol_text (s));
2304 tlen = ffecom_get_invented_identifier ("__g77_%s", "length");
2305 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
2306 DECL_ARTIFICIAL (tlen) = 1;
2309 if (sz == FFETARGET_charactersizeNONE)
2311 assert (tlen != NULL_TREE);
2312 highval = variable_size (tlen);
2316 highval = build_int_2 (sz, 0);
2317 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2320 type = build_array_type (type,
2321 build_range_type (ffecom_f2c_ftnlen_type_node,
2322 ffecom_f2c_ftnlen_one_node,
2329 /* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2331 ffecomConcatList_ catlist;
2332 ffebld expr; // expr of CHARACTER basictype.
2333 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2334 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2336 Scans expr for character subexpressions, updates and returns catlist
2339 static ffecomConcatList_
2340 ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2341 ffetargetCharacterSize max)
2343 ffetargetCharacterSize sz;
2350 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2351 return catlist; /* Don't append any more items. */
2353 switch (ffebld_op (expr))
2355 case FFEBLD_opCONTER:
2356 case FFEBLD_opSYMTER:
2357 case FFEBLD_opARRAYREF:
2358 case FFEBLD_opFUNCREF:
2359 case FFEBLD_opSUBSTR:
2360 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2361 if they don't need to preserve it. */
2362 if (catlist.count == catlist.max)
2363 { /* Make a (larger) list. */
2367 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2368 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2369 newmax * sizeof (newx[0]));
2370 if (catlist.max != 0)
2372 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2373 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2374 catlist.max * sizeof (newx[0]));
2376 catlist.max = newmax;
2377 catlist.exprs = newx;
2379 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2380 catlist.minlen += sz;
2382 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2383 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2384 catlist.maxlen = sz;
2386 catlist.maxlen += sz;
2387 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2388 { /* This item overlaps (or is beyond) the end
2389 of the destination. */
2390 switch (ffebld_op (expr))
2392 case FFEBLD_opCONTER:
2393 case FFEBLD_opSYMTER:
2394 case FFEBLD_opARRAYREF:
2395 case FFEBLD_opFUNCREF:
2396 case FFEBLD_opSUBSTR:
2397 /* ~~Do useful truncations here. */
2401 assert ("op changed or inconsistent switches!" == NULL);
2405 catlist.exprs[catlist.count++] = expr;
2408 case FFEBLD_opPAREN:
2409 expr = ffebld_left (expr);
2410 goto recurse; /* :::::::::::::::::::: */
2412 case FFEBLD_opCONCATENATE:
2413 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2414 expr = ffebld_right (expr);
2415 goto recurse; /* :::::::::::::::::::: */
2417 #if 0 /* Breaks passing small actual arg to larger
2418 dummy arg of sfunc */
2419 case FFEBLD_opCONVERT:
2420 expr = ffebld_left (expr);
2422 ffetargetCharacterSize cmax;
2424 cmax = catlist.len + ffebld_size_known (expr);
2426 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2429 goto recurse; /* :::::::::::::::::::: */
2436 assert ("bad op in _gather_" == NULL);
2441 /* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2443 ffecomConcatList_ catlist;
2444 ffecom_concat_list_kill_(catlist);
2446 Anything allocated within the list info is deallocated. */
2449 ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2451 if (catlist.max != 0)
2452 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2453 catlist.max * sizeof (catlist.exprs[0]));
2456 /* Make list of concatenated string exprs.
2458 Returns a flattened list of concatenated subexpressions given a
2459 tree of such expressions. */
2461 static ffecomConcatList_
2462 ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2464 ffecomConcatList_ catlist;
2466 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2467 return ffecom_concat_list_gather_ (catlist, expr, max);
2470 /* Provide some kind of useful info on member of aggregate area,
2471 since current g77/gcc technology does not provide debug info
2472 on these members. */
2475 ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
2476 tree member_type UNUSED, ffetargetOffset offset)
2486 for (type_id = member_type;
2487 TREE_CODE (type_id) != IDENTIFIER_NODE;
2490 switch (TREE_CODE (type_id))
2494 type_id = TYPE_NAME (type_id);
2499 type_id = TREE_TYPE (type_id);
2503 assert ("no IDENTIFIER_NODE for type!" == NULL);
2504 type_id = error_mark_node;
2510 if (ffecom_transform_only_dummies_
2511 || !ffe_is_debug_kludge ())
2512 return; /* Can't do this yet, maybe later. */
2515 + strlen (aggr_type)
2516 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2518 + IDENTIFIER_LENGTH (type_id);
2521 if (((size_t) len) >= ARRAY_SIZE (space))
2522 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2526 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2528 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2531 value = build_string (len, buff);
2533 = build_type_variant (build_array_type (char_type_node,
2537 build_int_2 (strlen (buff), 0))),
2539 decl = build_decl (VAR_DECL,
2540 ffecom_get_identifier_ (ffesymbol_text (member)),
2542 TREE_CONSTANT (decl) = 1;
2543 TREE_STATIC (decl) = 1;
2544 DECL_INITIAL (decl) = error_mark_node;
2545 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2546 decl = start_decl (decl, FALSE);
2547 finish_decl (decl, value, FALSE);
2549 if (buff != &space[0])
2550 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2553 /* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2555 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2556 int i; // entry# for this entrypoint (used by master fn)
2557 ffecom_do_entrypoint_(s,i);
2559 Makes a public entry point that calls our private master fn (already
2563 ffecom_do_entry_ (ffesymbol fn, int entrynum)
2566 tree type; /* Type of function. */
2567 tree multi_retval; /* Var holding return value (union). */
2568 tree result; /* Var holding result. */
2569 ffeinfoBasictype bt;
2573 bool charfunc; /* All entry points return same type
2575 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2576 bool multi; /* Master fn has multiple return types. */
2577 bool altreturning = FALSE; /* This entry point has alternate returns. */
2578 int old_lineno = lineno;
2579 const char *old_input_filename = input_filename;
2581 input_filename = ffesymbol_where_filename (fn);
2582 lineno = ffesymbol_where_filelinenum (fn);
2584 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2586 switch (ffecom_primary_entry_kind_)
2588 case FFEINFO_kindFUNCTION:
2590 /* Determine actual return type for function. */
2592 gt = FFEGLOBAL_typeFUNC;
2593 bt = ffesymbol_basictype (fn);
2594 kt = ffesymbol_kindtype (fn);
2595 if (bt == FFEINFO_basictypeNONE)
2597 ffeimplic_establish_symbol (fn);
2598 if (ffesymbol_funcresult (fn) != NULL)
2599 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2600 bt = ffesymbol_basictype (fn);
2601 kt = ffesymbol_kindtype (fn);
2604 if (bt == FFEINFO_basictypeCHARACTER)
2605 charfunc = TRUE, cmplxfunc = FALSE;
2606 else if ((bt == FFEINFO_basictypeCOMPLEX)
2607 && ffesymbol_is_f2c (fn))
2608 charfunc = FALSE, cmplxfunc = TRUE;
2610 charfunc = cmplxfunc = FALSE;
2613 type = ffecom_tree_fun_type_void;
2614 else if (ffesymbol_is_f2c (fn))
2615 type = ffecom_tree_fun_type[bt][kt];
2617 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2619 if ((type == NULL_TREE)
2620 || (TREE_TYPE (type) == NULL_TREE))
2621 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2623 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2626 case FFEINFO_kindSUBROUTINE:
2627 gt = FFEGLOBAL_typeSUBR;
2628 bt = FFEINFO_basictypeNONE;
2629 kt = FFEINFO_kindtypeNONE;
2630 if (ffecom_is_altreturning_)
2631 { /* Am _I_ altreturning? */
2632 for (item = ffesymbol_dummyargs (fn);
2634 item = ffebld_trail (item))
2636 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2638 altreturning = TRUE;
2643 type = ffecom_tree_subr_type;
2645 type = ffecom_tree_fun_type_void;
2648 type = ffecom_tree_fun_type_void;
2655 assert ("say what??" == NULL);
2657 case FFEINFO_kindANY:
2658 gt = FFEGLOBAL_typeANY;
2659 bt = FFEINFO_basictypeNONE;
2660 kt = FFEINFO_kindtypeNONE;
2661 type = error_mark_node;
2668 /* build_decl uses the current lineno and input_filename to set the decl
2669 source info. So, I've putzed with ffestd and ffeste code to update that
2670 source info to point to the appropriate statement just before calling
2671 ffecom_do_entrypoint (which calls this fn). */
2673 start_function (ffecom_get_external_identifier_ (fn),
2675 0, /* nested/inline */
2676 1); /* TREE_PUBLIC */
2678 if (((g = ffesymbol_global (fn)) != NULL)
2679 && ((ffeglobal_type (g) == gt)
2680 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2682 ffeglobal_set_hook (g, current_function_decl);
2685 /* Reset args in master arg list so they get retransitioned. */
2687 for (item = ffecom_master_arglist_;
2689 item = ffebld_trail (item))
2694 arg = ffebld_head (item);
2695 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2696 continue; /* Alternate return or some such thing. */
2697 s = ffebld_symter (arg);
2698 ffesymbol_hook (s).decl_tree = NULL_TREE;
2699 ffesymbol_hook (s).length_tree = NULL_TREE;
2702 /* Build dummy arg list for this entry point. */
2704 if (charfunc || cmplxfunc)
2705 { /* Prepend arg for where result goes. */
2710 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2712 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2714 result = ffecom_get_invented_identifier ("__g77_%s", "result");
2716 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2719 length = ffecom_char_enhance_arg_ (&type, fn);
2721 length = NULL_TREE; /* Not ref'd if !charfunc. */
2723 type = build_pointer_type (type);
2724 result = build_decl (PARM_DECL, result, type);
2726 push_parm_decl (result);
2727 ffecom_func_result_ = result;
2731 push_parm_decl (length);
2732 ffecom_func_length_ = length;
2736 result = DECL_RESULT (current_function_decl);
2738 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2740 store_parm_decls (0);
2742 ffecom_start_compstmt ();
2743 /* Disallow temp vars at this level. */
2744 current_binding_level->prep_state = 2;
2746 /* Make local var to hold return type for multi-type master fn. */
2750 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
2752 multi_retval = build_decl (VAR_DECL, multi_retval,
2753 ffecom_multi_type_node_);
2754 multi_retval = start_decl (multi_retval, FALSE);
2755 finish_decl (multi_retval, NULL_TREE, FALSE);
2758 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2760 /* Here we emit the actual code for the entry point. */
2766 tree arglist = NULL_TREE;
2767 tree *plist = &arglist;
2773 /* Prepare actual arg list based on master arg list. */
2775 for (list = ffecom_master_arglist_;
2777 list = ffebld_trail (list))
2779 arg = ffebld_head (list);
2780 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2782 s = ffebld_symter (arg);
2783 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2784 || ffesymbol_hook (s).decl_tree == error_mark_node)
2785 actarg = null_pointer_node; /* We don't have this arg. */
2787 actarg = ffesymbol_hook (s).decl_tree;
2788 *plist = build_tree_list (NULL_TREE, actarg);
2789 plist = &TREE_CHAIN (*plist);
2792 /* This code appends the length arguments for character
2793 variables/arrays. */
2795 for (list = ffecom_master_arglist_;
2797 list = ffebld_trail (list))
2799 arg = ffebld_head (list);
2800 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2802 s = ffebld_symter (arg);
2803 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2804 continue; /* Only looking for CHARACTER arguments. */
2805 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2806 continue; /* Only looking for variables and arrays. */
2807 if (ffesymbol_hook (s).length_tree == NULL_TREE
2808 || ffesymbol_hook (s).length_tree == error_mark_node)
2809 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2811 actarg = ffesymbol_hook (s).length_tree;
2812 *plist = build_tree_list (NULL_TREE, actarg);
2813 plist = &TREE_CHAIN (*plist);
2816 /* Prepend character-value return info to actual arg list. */
2820 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2821 TREE_CHAIN (prepend)
2822 = build_tree_list (NULL_TREE, ffecom_func_length_);
2823 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2827 /* Prepend multi-type return value to actual arg list. */
2832 = build_tree_list (NULL_TREE,
2833 ffecom_1 (ADDR_EXPR,
2834 build_pointer_type (TREE_TYPE (multi_retval)),
2836 TREE_CHAIN (prepend) = arglist;
2840 /* Prepend my entry-point number to the actual arg list. */
2842 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2843 TREE_CHAIN (prepend) = arglist;
2846 /* Build the call to the master function. */
2848 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2849 call = ffecom_3s (CALL_EXPR,
2850 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2851 master_fn, arglist, NULL_TREE);
2853 /* Decide whether the master function is a function or subroutine, and
2854 handle the return value for my entry point. */
2856 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2859 expand_expr_stmt (call);
2860 expand_null_return ();
2862 else if (multi && cmplxfunc)
2864 expand_expr_stmt (call);
2866 = ffecom_1 (INDIRECT_REF,
2867 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2869 result = ffecom_modify (NULL_TREE, result,
2870 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
2872 ffecom_multi_fields_[bt][kt]));
2873 expand_expr_stmt (result);
2874 expand_null_return ();
2878 expand_expr_stmt (call);
2880 = ffecom_modify (NULL_TREE, result,
2881 convert (TREE_TYPE (result),
2882 ffecom_2 (COMPONENT_REF,
2883 ffecom_tree_type[bt][kt],
2885 ffecom_multi_fields_[bt][kt])));
2886 expand_return (result);
2891 = ffecom_1 (INDIRECT_REF,
2892 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2894 result = ffecom_modify (NULL_TREE, result, call);
2895 expand_expr_stmt (result);
2896 expand_null_return ();
2900 result = ffecom_modify (NULL_TREE,
2902 convert (TREE_TYPE (result),
2904 expand_return (result);
2908 ffecom_end_compstmt ();
2910 finish_function (0);
2912 lineno = old_lineno;
2913 input_filename = old_input_filename;
2915 ffecom_doing_entry_ = FALSE;
2918 /* Transform expr into gcc tree with possible destination
2920 Recursive descent on expr while making corresponding tree nodes and
2921 attaching type info and such. If destination supplied and compatible
2922 with temporary that would be made in certain cases, temporary isn't
2923 made, destination used instead, and dest_used flag set TRUE. */
2926 ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
2927 bool *dest_used, bool assignp, bool widenp)
2932 ffeinfoBasictype bt;
2935 tree dt; /* decl_tree for an ffesymbol. */
2936 tree tree_type, tree_type_x;
2939 enum tree_code code;
2941 assert (expr != NULL);
2943 if (dest_used != NULL)
2946 bt = ffeinfo_basictype (ffebld_info (expr));
2947 kt = ffeinfo_kindtype (ffebld_info (expr));
2948 tree_type = ffecom_tree_type[bt][kt];
2950 /* Widen integral arithmetic as desired while preserving signedness. */
2951 tree_type_x = NULL_TREE;
2952 if (widenp && tree_type
2953 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
2954 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
2955 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
2957 switch (ffebld_op (expr))
2959 case FFEBLD_opACCTER:
2962 ffebit bits = ffebld_accter_bits (expr);
2963 ffetargetOffset source_offset = 0;
2964 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
2967 assert (dest_offset == 0
2968 || (bt == FFEINFO_basictypeCHARACTER
2969 && kt == FFEINFO_kindtypeCHARACTER1));
2974 ffebldConstantUnion cu;
2977 ffebldConstantArray ca = ffebld_accter (expr);
2979 ffebit_test (bits, source_offset, &value, &length);
2985 for (i = 0; i < length; ++i)
2987 cu = ffebld_constantarray_get (ca, bt, kt,
2990 t = ffecom_constantunion (&cu, bt, kt, tree_type);
2993 && dest_offset != 0)
2994 purpose = build_int_2 (dest_offset, 0);
2996 purpose = NULL_TREE;
2998 if (list == NULL_TREE)
2999 list = item = build_tree_list (purpose, t);
3002 TREE_CHAIN (item) = build_tree_list (purpose, t);
3003 item = TREE_CHAIN (item);
3007 source_offset += length;
3008 dest_offset += length;
3012 item = build_int_2 ((ffebld_accter_size (expr)
3013 + ffebld_accter_pad (expr)) - 1, 0);
3014 ffebit_kill (ffebld_accter_bits (expr));
3015 TREE_TYPE (item) = ffecom_integer_type_node;
3019 build_range_type (ffecom_integer_type_node,
3020 ffecom_integer_zero_node,
3022 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3023 TREE_CONSTANT (list) = 1;
3024 TREE_STATIC (list) = 1;
3027 case FFEBLD_opARRTER:
3032 if (ffebld_arrter_pad (expr) == 0)
3036 assert (bt == FFEINFO_basictypeCHARACTER
3037 && kt == FFEINFO_kindtypeCHARACTER1);
3039 /* Becomes PURPOSE first time through loop. */
3040 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3043 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3045 ffebldConstantUnion cu
3046 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3048 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3050 if (list == NULL_TREE)
3051 /* Assume item is PURPOSE first time through loop. */
3052 list = item = build_tree_list (item, t);
3055 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3056 item = TREE_CHAIN (item);
3061 item = build_int_2 ((ffebld_arrter_size (expr)
3062 + ffebld_arrter_pad (expr)) - 1, 0);
3063 TREE_TYPE (item) = ffecom_integer_type_node;
3067 build_range_type (ffecom_integer_type_node,
3068 ffecom_integer_zero_node,
3070 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3071 TREE_CONSTANT (list) = 1;
3072 TREE_STATIC (list) = 1;
3075 case FFEBLD_opCONTER:
3076 assert (ffebld_conter_pad (expr) == 0);
3078 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3082 case FFEBLD_opSYMTER:
3083 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3084 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3085 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3086 s = ffebld_symter (expr);
3087 t = ffesymbol_hook (s).decl_tree;
3090 { /* ASSIGN'ed-label expr. */
3091 if (ffe_is_ugly_assign ())
3093 /* User explicitly wants ASSIGN'ed variables to be at the same
3094 memory address as the variables when used in non-ASSIGN
3095 contexts. That can make old, arcane, non-standard code
3096 work, but don't try to do it when a pointer wouldn't fit
3097 in the normal variable (take other approach, and warn,
3102 s = ffecom_sym_transform_ (s);
3103 t = ffesymbol_hook (s).decl_tree;
3104 assert (t != NULL_TREE);
3107 if (t == error_mark_node)
3110 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3111 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3113 if (ffesymbol_hook (s).addr)
3114 t = ffecom_1 (INDIRECT_REF,
3115 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3119 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3121 /* xgettext:no-c-format */
3122 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3123 FFEBAD_severityWARNING);
3124 ffebad_string (ffesymbol_text (s));
3125 ffebad_here (0, ffesymbol_where_line (s),
3126 ffesymbol_where_column (s));
3131 /* Don't use the normal variable's tree for ASSIGN, though mark
3132 it as in the system header (housekeeping). Use an explicit,
3133 specially created sibling that is known to be wide enough
3134 to hold pointers to labels. */
3137 && TREE_CODE (t) == VAR_DECL)
3138 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3140 t = ffesymbol_hook (s).assign_tree;
3143 s = ffecom_sym_transform_assign_ (s);
3144 t = ffesymbol_hook (s).assign_tree;
3145 assert (t != NULL_TREE);
3152 s = ffecom_sym_transform_ (s);
3153 t = ffesymbol_hook (s).decl_tree;
3154 assert (t != NULL_TREE);
3156 if (ffesymbol_hook (s).addr)
3157 t = ffecom_1 (INDIRECT_REF,
3158 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3162 case FFEBLD_opARRAYREF:
3163 return ffecom_arrayref_ (NULL_TREE, expr, 0);
3165 case FFEBLD_opUPLUS:
3166 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3167 return ffecom_1 (NOP_EXPR, tree_type, left);
3169 case FFEBLD_opPAREN:
3170 /* ~~~Make sure Fortran rules respected here */
3171 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3172 return ffecom_1 (NOP_EXPR, tree_type, left);
3174 case FFEBLD_opUMINUS:
3175 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3178 tree_type = tree_type_x;
3179 left = convert (tree_type, left);
3181 return ffecom_1 (NEGATE_EXPR, tree_type, left);
3184 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3185 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3188 tree_type = tree_type_x;
3189 left = convert (tree_type, left);
3190 right = convert (tree_type, right);
3192 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
3194 case FFEBLD_opSUBTRACT:
3195 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3196 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3199 tree_type = tree_type_x;
3200 left = convert (tree_type, left);
3201 right = convert (tree_type, right);
3203 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
3205 case FFEBLD_opMULTIPLY:
3206 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3207 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3210 tree_type = tree_type_x;
3211 left = convert (tree_type, left);
3212 right = convert (tree_type, right);
3214 return ffecom_2 (MULT_EXPR, tree_type, left, right);
3216 case FFEBLD_opDIVIDE:
3217 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3218 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3221 tree_type = tree_type_x;
3222 left = convert (tree_type, left);
3223 right = convert (tree_type, right);
3225 return ffecom_tree_divide_ (tree_type, left, right,
3226 dest_tree, dest, dest_used,
3227 ffebld_nonter_hook (expr));
3229 case FFEBLD_opPOWER:
3231 ffebld left = ffebld_left (expr);
3232 ffebld right = ffebld_right (expr);
3234 ffeinfoKindtype rtkt;
3235 ffeinfoKindtype ltkt;
3238 switch (ffeinfo_basictype (ffebld_info (right)))
3241 case FFEINFO_basictypeINTEGER:
3244 item = ffecom_expr_power_integer_ (expr);
3245 if (item != NULL_TREE)
3249 rtkt = FFEINFO_kindtypeINTEGER1;
3250 switch (ffeinfo_basictype (ffebld_info (left)))
3252 case FFEINFO_basictypeINTEGER:
3253 if ((ffeinfo_kindtype (ffebld_info (left))
3254 == FFEINFO_kindtypeINTEGER4)
3255 || (ffeinfo_kindtype (ffebld_info (right))
3256 == FFEINFO_kindtypeINTEGER4))
3258 code = FFECOM_gfrtPOW_QQ;
3259 ltkt = FFEINFO_kindtypeINTEGER4;
3260 rtkt = FFEINFO_kindtypeINTEGER4;
3264 code = FFECOM_gfrtPOW_II;
3265 ltkt = FFEINFO_kindtypeINTEGER1;
3269 case FFEINFO_basictypeREAL:
3270 if (ffeinfo_kindtype (ffebld_info (left))
3271 == FFEINFO_kindtypeREAL1)
3273 code = FFECOM_gfrtPOW_RI;
3274 ltkt = FFEINFO_kindtypeREAL1;
3278 code = FFECOM_gfrtPOW_DI;
3279 ltkt = FFEINFO_kindtypeREAL2;
3283 case FFEINFO_basictypeCOMPLEX:
3284 if (ffeinfo_kindtype (ffebld_info (left))
3285 == FFEINFO_kindtypeREAL1)
3287 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3288 ltkt = FFEINFO_kindtypeREAL1;
3292 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3293 ltkt = FFEINFO_kindtypeREAL2;
3298 assert ("bad pow_*i" == NULL);
3299 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3300 ltkt = FFEINFO_kindtypeREAL1;
3303 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
3304 left = ffeexpr_convert (left, NULL, NULL,
3305 ffeinfo_basictype (ffebld_info (left)),
3307 FFETARGET_charactersizeNONE,
3308 FFEEXPR_contextLET);
3309 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3310 right = ffeexpr_convert (right, NULL, NULL,
3311 FFEINFO_basictypeINTEGER,
3313 FFETARGET_charactersizeNONE,
3314 FFEEXPR_contextLET);
3317 case FFEINFO_basictypeREAL:
3318 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3319 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3320 FFEINFO_kindtypeREALDOUBLE, 0,
3321 FFETARGET_charactersizeNONE,
3322 FFEEXPR_contextLET);
3323 if (ffeinfo_kindtype (ffebld_info (right))
3324 == FFEINFO_kindtypeREAL1)
3325 right = ffeexpr_convert (right, NULL, NULL,
3326 FFEINFO_basictypeREAL,
3327 FFEINFO_kindtypeREALDOUBLE, 0,
3328 FFETARGET_charactersizeNONE,
3329 FFEEXPR_contextLET);
3330 /* We used to call FFECOM_gfrtPOW_DD here,
3331 which passes arguments by reference. */
3332 code = FFECOM_gfrtL_POW;
3333 /* Pass arguments by value. */
3337 case FFEINFO_basictypeCOMPLEX:
3338 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3339 left = ffeexpr_convert (left, NULL, NULL,
3340 FFEINFO_basictypeCOMPLEX,
3341 FFEINFO_kindtypeREALDOUBLE, 0,
3342 FFETARGET_charactersizeNONE,
3343 FFEEXPR_contextLET);
3344 if (ffeinfo_kindtype (ffebld_info (right))
3345 == FFEINFO_kindtypeREAL1)
3346 right = ffeexpr_convert (right, NULL, NULL,
3347 FFEINFO_basictypeCOMPLEX,
3348 FFEINFO_kindtypeREALDOUBLE, 0,
3349 FFETARGET_charactersizeNONE,
3350 FFEEXPR_contextLET);
3351 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
3352 ref = TRUE; /* Pass arguments by reference. */
3356 assert ("bad pow_x*" == NULL);
3357 code = FFECOM_gfrtPOW_II;
3360 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3361 ffecom_gfrt_kindtype (code),
3362 (ffe_is_f2c_library ()
3363 && ffecom_gfrt_complex_[code]),
3364 tree_type, left, right,
3365 dest_tree, dest, dest_used,
3366 NULL_TREE, FALSE, ref,
3367 ffebld_nonter_hook (expr));
3373 case FFEINFO_basictypeLOGICAL:
3374 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
3375 return convert (tree_type, item);
3377 case FFEINFO_basictypeINTEGER:
3378 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3379 ffecom_expr (ffebld_left (expr)));
3382 assert ("NOT bad basictype" == NULL);
3384 case FFEINFO_basictypeANY:
3385 return error_mark_node;
3389 case FFEBLD_opFUNCREF:
3390 assert (ffeinfo_basictype (ffebld_info (expr))
3391 != FFEINFO_basictypeCHARACTER);
3393 case FFEBLD_opSUBRREF:
3394 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3395 == FFEINFO_whereINTRINSIC)
3396 { /* Invocation of an intrinsic. */
3397 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3401 s = ffebld_symter (ffebld_left (expr));
3402 dt = ffesymbol_hook (s).decl_tree;
3403 if (dt == NULL_TREE)
3405 s = ffecom_sym_transform_ (s);
3406 dt = ffesymbol_hook (s).decl_tree;
3408 if (dt == error_mark_node)
3411 if (ffesymbol_hook (s).addr)
3414 item = ffecom_1_fn (dt);
3416 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3417 args = ffecom_list_expr (ffebld_right (expr));
3419 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
3421 if (args == error_mark_node)
3422 return error_mark_node;
3424 item = ffecom_call_ (item, kt,
3425 ffesymbol_is_f2c (s)
3426 && (bt == FFEINFO_basictypeCOMPLEX)
3427 && (ffesymbol_where (s)
3428 != FFEINFO_whereCONSTANT),
3431 dest_tree, dest, dest_used,
3432 error_mark_node, FALSE,
3433 ffebld_nonter_hook (expr));
3434 TREE_SIDE_EFFECTS (item) = 1;
3440 case FFEINFO_basictypeLOGICAL:
3442 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3443 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3444 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3445 return convert (tree_type, item);
3447 case FFEINFO_basictypeINTEGER:
3448 return ffecom_2 (BIT_AND_EXPR, tree_type,
3449 ffecom_expr (ffebld_left (expr)),
3450 ffecom_expr (ffebld_right (expr)));
3453 assert ("AND bad basictype" == NULL);
3455 case FFEINFO_basictypeANY:
3456 return error_mark_node;
3463 case FFEINFO_basictypeLOGICAL:
3465 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3466 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3467 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3468 return convert (tree_type, item);
3470 case FFEINFO_basictypeINTEGER:
3471 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3472 ffecom_expr (ffebld_left (expr)),
3473 ffecom_expr (ffebld_right (expr)));
3476 assert ("OR bad basictype" == NULL);
3478 case FFEINFO_basictypeANY:
3479 return error_mark_node;
3487 case FFEINFO_basictypeLOGICAL:
3489 = ffecom_2 (NE_EXPR, integer_type_node,
3490 ffecom_expr (ffebld_left (expr)),
3491 ffecom_expr (ffebld_right (expr)));
3492 return convert (tree_type, ffecom_truth_value (item));
3494 case FFEINFO_basictypeINTEGER:
3495 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3496 ffecom_expr (ffebld_left (expr)),
3497 ffecom_expr (ffebld_right (expr)));
3500 assert ("XOR/NEQV bad basictype" == NULL);
3502 case FFEINFO_basictypeANY:
3503 return error_mark_node;
3510 case FFEINFO_basictypeLOGICAL:
3512 = ffecom_2 (EQ_EXPR, integer_type_node,
3513 ffecom_expr (ffebld_left (expr)),
3514 ffecom_expr (ffebld_right (expr)));
3515 return convert (tree_type, ffecom_truth_value (item));
3517 case FFEINFO_basictypeINTEGER:
3519 ffecom_1 (BIT_NOT_EXPR, tree_type,
3520 ffecom_2 (BIT_XOR_EXPR, tree_type,
3521 ffecom_expr (ffebld_left (expr)),
3522 ffecom_expr (ffebld_right (expr))));
3525 assert ("EQV bad basictype" == NULL);
3527 case FFEINFO_basictypeANY:
3528 return error_mark_node;
3532 case FFEBLD_opCONVERT:
3533 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3534 return error_mark_node;
3538 case FFEINFO_basictypeLOGICAL:
3539 case FFEINFO_basictypeINTEGER:
3540 case FFEINFO_basictypeREAL:
3541 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3543 case FFEINFO_basictypeCOMPLEX:
3544 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3546 case FFEINFO_basictypeINTEGER:
3547 case FFEINFO_basictypeLOGICAL:
3548 case FFEINFO_basictypeREAL:
3549 item = ffecom_expr (ffebld_left (expr));
3550 if (item == error_mark_node)
3551 return error_mark_node;
3552 /* convert() takes care of converting to the subtype first,
3553 at least in gcc-2.7.2. */
3554 item = convert (tree_type, item);
3557 case FFEINFO_basictypeCOMPLEX:
3558 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3561 assert ("CONVERT COMPLEX bad basictype" == NULL);
3563 case FFEINFO_basictypeANY:
3564 return error_mark_node;
3569 assert ("CONVERT bad basictype" == NULL);
3571 case FFEINFO_basictypeANY:
3572 return error_mark_node;
3578 goto relational; /* :::::::::::::::::::: */
3582 goto relational; /* :::::::::::::::::::: */
3586 goto relational; /* :::::::::::::::::::: */
3590 goto relational; /* :::::::::::::::::::: */
3594 goto relational; /* :::::::::::::::::::: */
3599 relational: /* :::::::::::::::::::: */
3600 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3602 case FFEINFO_basictypeLOGICAL:
3603 case FFEINFO_basictypeINTEGER:
3604 case FFEINFO_basictypeREAL:
3605 item = ffecom_2 (code, integer_type_node,
3606 ffecom_expr (ffebld_left (expr)),
3607 ffecom_expr (ffebld_right (expr)));
3608 return convert (tree_type, item);
3610 case FFEINFO_basictypeCOMPLEX:
3611 assert (code == EQ_EXPR || code == NE_EXPR);
3614 tree arg1 = ffecom_expr (ffebld_left (expr));
3615 tree arg2 = ffecom_expr (ffebld_right (expr));
3617 if (arg1 == error_mark_node || arg2 == error_mark_node)
3618 return error_mark_node;
3620 arg1 = ffecom_save_tree (arg1);
3621 arg2 = ffecom_save_tree (arg2);
3623 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3625 real_type = TREE_TYPE (TREE_TYPE (arg1));
3626 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3630 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3631 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3635 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3636 ffecom_2 (EQ_EXPR, integer_type_node,
3637 ffecom_1 (REALPART_EXPR, real_type, arg1),
3638 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3639 ffecom_2 (EQ_EXPR, integer_type_node,
3640 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3641 ffecom_1 (IMAGPART_EXPR, real_type,
3643 if (code == EQ_EXPR)
3644 item = ffecom_truth_value (item);
3646 item = ffecom_truth_value_invert (item);
3647 return convert (tree_type, item);
3650 case FFEINFO_basictypeCHARACTER:
3652 ffebld left = ffebld_left (expr);
3653 ffebld right = ffebld_right (expr);
3659 /* f2c run-time functions do the implicit blank-padding for us,
3660 so we don't usually have to implement blank-padding ourselves.
3661 (The exception is when we pass an argument to a separately
3662 compiled statement function -- if we know the arg is not the
3663 same length as the dummy, we must truncate or extend it. If
3664 we "inline" statement functions, that necessity goes away as
3667 Strip off the CONVERT operators that blank-pad. (Truncation by
3668 CONVERT shouldn't happen here, but it can happen in
3671 while (ffebld_op (left) == FFEBLD_opCONVERT)
3672 left = ffebld_left (left);
3673 while (ffebld_op (right) == FFEBLD_opCONVERT)
3674 right = ffebld_left (right);
3676 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3677 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3679 if (left_tree == error_mark_node || left_length == error_mark_node
3680 || right_tree == error_mark_node
3681 || right_length == error_mark_node)
3682 return error_mark_node;
3684 if ((ffebld_size_known (left) == 1)
3685 && (ffebld_size_known (right) == 1))
3688 = ffecom_1 (INDIRECT_REF,
3689 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3692 = ffecom_1 (INDIRECT_REF,
3693 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3697 = ffecom_2 (code, integer_type_node,
3698 ffecom_2 (ARRAY_REF,
3699 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3702 ffecom_2 (ARRAY_REF,
3703 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3709 item = build_tree_list (NULL_TREE, left_tree);
3710 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3711 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3713 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3714 = build_tree_list (NULL_TREE, right_length);
3715 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
3716 item = ffecom_2 (code, integer_type_node,
3718 convert (TREE_TYPE (item),
3719 integer_zero_node));
3721 item = convert (tree_type, item);
3727 assert ("relational bad basictype" == NULL);
3729 case FFEINFO_basictypeANY:
3730 return error_mark_node;
3734 case FFEBLD_opPERCENT_LOC:
3735 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3736 return convert (tree_type, item);
3738 case FFEBLD_opPERCENT_VAL:
3739 item = ffecom_arg_expr (ffebld_left (expr), &list);
3740 return convert (tree_type, item);
3744 case FFEBLD_opBOUNDS:
3745 case FFEBLD_opREPEAT:
3746 case FFEBLD_opLABTER:
3747 case FFEBLD_opLABTOK:
3748 case FFEBLD_opIMPDO:
3749 case FFEBLD_opCONCATENATE:
3750 case FFEBLD_opSUBSTR:
3752 assert ("bad op" == NULL);
3755 return error_mark_node;
3759 assert ("didn't think anything got here anymore!!" == NULL);
3761 switch (ffebld_arity (expr))
3764 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3765 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3766 if (TREE_OPERAND (item, 0) == error_mark_node
3767 || TREE_OPERAND (item, 1) == error_mark_node)
3768 return error_mark_node;
3772 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3773 if (TREE_OPERAND (item, 0) == error_mark_node)
3774 return error_mark_node;
3785 /* Returns the tree that does the intrinsic invocation.
3787 Note: this function applies only to intrinsics returning
3788 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3792 ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
3793 ffebld dest, bool *dest_used)
3796 tree saved_expr1; /* For those who need it. */
3797 tree saved_expr2; /* For those who need it. */
3798 ffeinfoBasictype bt;
3802 tree real_type; /* REAL type corresponding to COMPLEX. */
3804 ffebld list = ffebld_right (expr); /* List of (some) args. */
3805 ffebld arg1; /* For handy reference. */
3808 ffeintrinImp codegen_imp;
3811 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3813 if (dest_used != NULL)
3816 bt = ffeinfo_basictype (ffebld_info (expr));
3817 kt = ffeinfo_kindtype (ffebld_info (expr));
3818 tree_type = ffecom_tree_type[bt][kt];
3822 arg1 = ffebld_head (list);
3823 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3824 return error_mark_node;
3825 if ((list = ffebld_trail (list)) != NULL)
3827 arg2 = ffebld_head (list);
3828 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3829 return error_mark_node;
3830 if ((list = ffebld_trail (list)) != NULL)
3832 arg3 = ffebld_head (list);
3833 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3834 return error_mark_node;
3843 arg1 = arg2 = arg3 = NULL;
3845 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3846 args. This is used by the MAX/MIN expansions. */
3849 arg1_type = ffecom_tree_type
3850 [ffeinfo_basictype (ffebld_info (arg1))]
3851 [ffeinfo_kindtype (ffebld_info (arg1))];
3853 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3856 /* There are several ways for each of the cases in the following switch
3857 statements to exit (from simplest to use to most complicated):
3859 break; (when expr_tree == NULL)
3861 A standard call is made to the specific intrinsic just as if it had been
3862 passed in as a dummy procedure and called as any old procedure. This
3863 method can produce slower code but in some cases it's the easiest way for
3864 now. However, if a (presumably faster) direct call is available,
3865 that is used, so this is the easiest way in many more cases now.
3867 gfrt = FFECOM_gfrtWHATEVER;
3870 gfrt contains the gfrt index of a library function to call, passing the
3871 argument(s) by value rather than by reference. Used when a more
3872 careful choice of library function is needed than that provided
3873 by the vanilla `break;'.
3877 The expr_tree has been completely set up and is ready to be returned
3878 as is. No further actions are taken. Use this when the tree is not
3879 in the simple form for one of the arity_n labels. */
3881 /* For info on how the switch statement cases were written, see the files
3882 enclosed in comments below the switch statement. */
3884 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
3885 gfrt = ffeintrin_gfrt_direct (codegen_imp);
3886 if (gfrt == FFECOM_gfrt)
3887 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
3889 switch (codegen_imp)
3891 case FFEINTRIN_impABS:
3892 case FFEINTRIN_impCABS:
3893 case FFEINTRIN_impCDABS:
3894 case FFEINTRIN_impDABS:
3895 case FFEINTRIN_impIABS:
3896 if (ffeinfo_basictype (ffebld_info (arg1))
3897 == FFEINFO_basictypeCOMPLEX)
3899 if (kt == FFEINFO_kindtypeREAL1)
3900 gfrt = FFECOM_gfrtCABS;
3901 else if (kt == FFEINFO_kindtypeREAL2)
3902 gfrt = FFECOM_gfrtCDABS;
3905 return ffecom_1 (ABS_EXPR, tree_type,
3906 convert (tree_type, ffecom_expr (arg1)));
3908 case FFEINTRIN_impACOS:
3909 case FFEINTRIN_impDACOS:
3912 case FFEINTRIN_impAIMAG:
3913 case FFEINTRIN_impDIMAG:
3914 case FFEINTRIN_impIMAGPART:
3915 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
3916 arg1_type = TREE_TYPE (arg1_type);
3918 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
3922 ffecom_1 (IMAGPART_EXPR, arg1_type,
3923 ffecom_expr (arg1)));
3925 case FFEINTRIN_impAINT:
3926 case FFEINTRIN_impDINT:
3928 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
3929 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
3930 #else /* in the meantime, must use floor to avoid range problems with ints */
3931 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
3932 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3935 ffecom_3 (COND_EXPR, double_type_node,
3937 (ffecom_2 (GE_EXPR, integer_type_node,
3940 ffecom_float_zero_))),
3941 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3942 build_tree_list (NULL_TREE,
3943 convert (double_type_node,
3946 ffecom_1 (NEGATE_EXPR, double_type_node,
3947 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3948 build_tree_list (NULL_TREE,
3949 convert (double_type_node,
3950 ffecom_1 (NEGATE_EXPR,
3958 case FFEINTRIN_impANINT:
3959 case FFEINTRIN_impDNINT:
3960 #if 0 /* This way of doing it won't handle real
3961 numbers of large magnitudes. */
3962 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3963 expr_tree = convert (tree_type,
3964 convert (integer_type_node,
3965 ffecom_3 (COND_EXPR, tree_type,
3970 ffecom_float_zero_)),
3971 ffecom_2 (PLUS_EXPR,
3974 ffecom_float_half_),
3975 ffecom_2 (MINUS_EXPR,
3978 ffecom_float_half_))));
3980 #else /* So we instead call floor. */
3981 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
3982 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3985 ffecom_3 (COND_EXPR, double_type_node,
3987 (ffecom_2 (GE_EXPR, integer_type_node,
3990 ffecom_float_zero_))),
3991 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3992 build_tree_list (NULL_TREE,
3993 convert (double_type_node,
3994 ffecom_2 (PLUS_EXPR,
3998 ffecom_float_half_)))),
4000 ffecom_1 (NEGATE_EXPR, double_type_node,
4001 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4002 build_tree_list (NULL_TREE,
4003 convert (double_type_node,
4004 ffecom_2 (MINUS_EXPR,
4007 ffecom_float_half_),
4014 case FFEINTRIN_impASIN:
4015 case FFEINTRIN_impDASIN:
4016 case FFEINTRIN_impATAN:
4017 case FFEINTRIN_impDATAN:
4018 case FFEINTRIN_impATAN2:
4019 case FFEINTRIN_impDATAN2:
4022 case FFEINTRIN_impCHAR:
4023 case FFEINTRIN_impACHAR:
4025 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
4027 tempvar = ffebld_nonter_hook (expr);
4031 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4033 expr_tree = ffecom_modify (tmv,
4034 ffecom_2 (ARRAY_REF, tmv, tempvar,
4036 convert (tmv, ffecom_expr (arg1)));
4038 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4041 expr_tree = ffecom_1 (ADDR_EXPR,
4042 build_pointer_type (TREE_TYPE (expr_tree)),
4046 case FFEINTRIN_impCMPLX:
4047 case FFEINTRIN_impDCMPLX:
4050 convert (tree_type, ffecom_expr (arg1));
4052 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4054 ffecom_2 (COMPLEX_EXPR, tree_type,
4055 convert (real_type, ffecom_expr (arg1)),
4057 ffecom_expr (arg2)));
4059 case FFEINTRIN_impCOMPLEX:
4061 ffecom_2 (COMPLEX_EXPR, tree_type,
4063 ffecom_expr (arg2));
4065 case FFEINTRIN_impCONJG:
4066 case FFEINTRIN_impDCONJG:
4070 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4071 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4073 ffecom_2 (COMPLEX_EXPR, tree_type,
4074 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4075 ffecom_1 (NEGATE_EXPR, real_type,
4076 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4079 case FFEINTRIN_impCOS:
4080 case FFEINTRIN_impCCOS:
4081 case FFEINTRIN_impCDCOS:
4082 case FFEINTRIN_impDCOS:
4083 if (bt == FFEINFO_basictypeCOMPLEX)
4085 if (kt == FFEINFO_kindtypeREAL1)
4086 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4087 else if (kt == FFEINFO_kindtypeREAL2)
4088 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4092 case FFEINTRIN_impCOSH:
4093 case FFEINTRIN_impDCOSH:
4096 case FFEINTRIN_impDBLE:
4097 case FFEINTRIN_impDFLOAT:
4098 case FFEINTRIN_impDREAL:
4099 case FFEINTRIN_impFLOAT:
4100 case FFEINTRIN_impIDINT:
4101 case FFEINTRIN_impIFIX:
4102 case FFEINTRIN_impINT2:
4103 case FFEINTRIN_impINT8:
4104 case FFEINTRIN_impINT:
4105 case FFEINTRIN_impLONG:
4106 case FFEINTRIN_impREAL:
4107 case FFEINTRIN_impSHORT:
4108 case FFEINTRIN_impSNGL:
4109 return convert (tree_type, ffecom_expr (arg1));
4111 case FFEINTRIN_impDIM:
4112 case FFEINTRIN_impDDIM:
4113 case FFEINTRIN_impIDIM:
4114 saved_expr1 = ffecom_save_tree (convert (tree_type,
4115 ffecom_expr (arg1)));
4116 saved_expr2 = ffecom_save_tree (convert (tree_type,
4117 ffecom_expr (arg2)));
4119 ffecom_3 (COND_EXPR, tree_type,
4121 (ffecom_2 (GT_EXPR, integer_type_node,
4124 ffecom_2 (MINUS_EXPR, tree_type,
4127 convert (tree_type, ffecom_float_zero_));
4129 case FFEINTRIN_impDPROD:
4131 ffecom_2 (MULT_EXPR, tree_type,
4132 convert (tree_type, ffecom_expr (arg1)),
4133 convert (tree_type, ffecom_expr (arg2)));
4135 case FFEINTRIN_impEXP:
4136 case FFEINTRIN_impCDEXP:
4137 case FFEINTRIN_impCEXP:
4138 case FFEINTRIN_impDEXP:
4139 if (bt == FFEINFO_basictypeCOMPLEX)
4141 if (kt == FFEINFO_kindtypeREAL1)
4142 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4143 else if (kt == FFEINFO_kindtypeREAL2)
4144 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4148 case FFEINTRIN_impICHAR:
4149 case FFEINTRIN_impIACHAR:
4150 #if 0 /* The simple approach. */
4151 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4153 = ffecom_1 (INDIRECT_REF,
4154 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4157 = ffecom_2 (ARRAY_REF,
4158 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4161 return convert (tree_type, expr_tree);
4162 #else /* The more interesting (and more optimal) approach. */
4163 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4164 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4167 convert (tree_type, integer_zero_node));
4171 case FFEINTRIN_impINDEX:
4174 case FFEINTRIN_impLEN:
4176 break; /* The simple approach. */
4178 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4181 case FFEINTRIN_impLGE:
4182 case FFEINTRIN_impLGT:
4183 case FFEINTRIN_impLLE:
4184 case FFEINTRIN_impLLT:
4187 case FFEINTRIN_impLOG:
4188 case FFEINTRIN_impALOG:
4189 case FFEINTRIN_impCDLOG:
4190 case FFEINTRIN_impCLOG:
4191 case FFEINTRIN_impDLOG:
4192 if (bt == FFEINFO_basictypeCOMPLEX)
4194 if (kt == FFEINFO_kindtypeREAL1)
4195 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4196 else if (kt == FFEINFO_kindtypeREAL2)
4197 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4201 case FFEINTRIN_impLOG10:
4202 case FFEINTRIN_impALOG10:
4203 case FFEINTRIN_impDLOG10:
4204 if (gfrt != FFECOM_gfrt)
4205 break; /* Already picked one, stick with it. */
4207 if (kt == FFEINFO_kindtypeREAL1)
4208 /* We used to call FFECOM_gfrtALOG10 here. */
4209 gfrt = FFECOM_gfrtL_LOG10;
4210 else if (kt == FFEINFO_kindtypeREAL2)
4211 /* We used to call FFECOM_gfrtDLOG10 here. */
4212 gfrt = FFECOM_gfrtL_LOG10;
4215 case FFEINTRIN_impMAX:
4216 case FFEINTRIN_impAMAX0:
4217 case FFEINTRIN_impAMAX1:
4218 case FFEINTRIN_impDMAX1:
4219 case FFEINTRIN_impMAX0:
4220 case FFEINTRIN_impMAX1:
4221 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4222 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4224 arg1_type = tree_type;
4225 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4226 convert (arg1_type, ffecom_expr (arg1)),
4227 convert (arg1_type, ffecom_expr (arg2)));
4228 for (; list != NULL; list = ffebld_trail (list))
4230 if ((ffebld_head (list) == NULL)
4231 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4233 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4236 ffecom_expr (ffebld_head (list))));
4238 return convert (tree_type, expr_tree);
4240 case FFEINTRIN_impMIN:
4241 case FFEINTRIN_impAMIN0:
4242 case FFEINTRIN_impAMIN1:
4243 case FFEINTRIN_impDMIN1:
4244 case FFEINTRIN_impMIN0:
4245 case FFEINTRIN_impMIN1:
4246 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4247 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4249 arg1_type = tree_type;
4250 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4251 convert (arg1_type, ffecom_expr (arg1)),
4252 convert (arg1_type, ffecom_expr (arg2)));
4253 for (; list != NULL; list = ffebld_trail (list))
4255 if ((ffebld_head (list) == NULL)
4256 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4258 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4261 ffecom_expr (ffebld_head (list))));
4263 return convert (tree_type, expr_tree);
4265 case FFEINTRIN_impMOD:
4266 case FFEINTRIN_impAMOD:
4267 case FFEINTRIN_impDMOD:
4268 if (bt != FFEINFO_basictypeREAL)
4269 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4270 convert (tree_type, ffecom_expr (arg1)),
4271 convert (tree_type, ffecom_expr (arg2)));
4273 if (kt == FFEINFO_kindtypeREAL1)
4274 /* We used to call FFECOM_gfrtAMOD here. */
4275 gfrt = FFECOM_gfrtL_FMOD;
4276 else if (kt == FFEINFO_kindtypeREAL2)
4277 /* We used to call FFECOM_gfrtDMOD here. */
4278 gfrt = FFECOM_gfrtL_FMOD;
4281 case FFEINTRIN_impNINT:
4282 case FFEINTRIN_impIDNINT:
4284 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
4285 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4287 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4288 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4290 convert (ffecom_integer_type_node,
4291 ffecom_3 (COND_EXPR, arg1_type,
4293 (ffecom_2 (GE_EXPR, integer_type_node,
4296 ffecom_float_zero_))),
4297 ffecom_2 (PLUS_EXPR, arg1_type,
4300 ffecom_float_half_)),
4301 ffecom_2 (MINUS_EXPR, arg1_type,
4304 ffecom_float_half_))));
4307 case FFEINTRIN_impSIGN:
4308 case FFEINTRIN_impDSIGN:
4309 case FFEINTRIN_impISIGN:
4311 tree arg2_tree = ffecom_expr (arg2);
4315 (ffecom_1 (ABS_EXPR, tree_type,
4317 ffecom_expr (arg1))));
4319 = ffecom_3 (COND_EXPR, tree_type,
4321 (ffecom_2 (GE_EXPR, integer_type_node,
4323 convert (TREE_TYPE (arg2_tree),
4324 integer_zero_node))),
4326 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4327 /* Make sure SAVE_EXPRs get referenced early enough. */
4329 = ffecom_2 (COMPOUND_EXPR, tree_type,
4330 convert (void_type_node, saved_expr1),
4335 case FFEINTRIN_impSIN:
4336 case FFEINTRIN_impCDSIN:
4337 case FFEINTRIN_impCSIN:
4338 case FFEINTRIN_impDSIN:
4339 if (bt == FFEINFO_basictypeCOMPLEX)
4341 if (kt == FFEINFO_kindtypeREAL1)
4342 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4343 else if (kt == FFEINFO_kindtypeREAL2)
4344 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4348 case FFEINTRIN_impSINH:
4349 case FFEINTRIN_impDSINH:
4352 case FFEINTRIN_impSQRT:
4353 case FFEINTRIN_impCDSQRT:
4354 case FFEINTRIN_impCSQRT:
4355 case FFEINTRIN_impDSQRT:
4356 if (bt == FFEINFO_basictypeCOMPLEX)
4358 if (kt == FFEINFO_kindtypeREAL1)
4359 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4360 else if (kt == FFEINFO_kindtypeREAL2)
4361 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4365 case FFEINTRIN_impTAN:
4366 case FFEINTRIN_impDTAN:
4367 case FFEINTRIN_impTANH:
4368 case FFEINTRIN_impDTANH:
4371 case FFEINTRIN_impREALPART:
4372 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4373 arg1_type = TREE_TYPE (arg1_type);
4375 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4379 ffecom_1 (REALPART_EXPR, arg1_type,
4380 ffecom_expr (arg1)));
4382 case FFEINTRIN_impIAND:
4383 case FFEINTRIN_impAND:
4384 return ffecom_2 (BIT_AND_EXPR, tree_type,
4386 ffecom_expr (arg1)),
4388 ffecom_expr (arg2)));
4390 case FFEINTRIN_impIOR:
4391 case FFEINTRIN_impOR:
4392 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4394 ffecom_expr (arg1)),
4396 ffecom_expr (arg2)));
4398 case FFEINTRIN_impIEOR:
4399 case FFEINTRIN_impXOR:
4400 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4402 ffecom_expr (arg1)),
4404 ffecom_expr (arg2)));
4406 case FFEINTRIN_impLSHIFT:
4407 return ffecom_2 (LSHIFT_EXPR, tree_type,
4409 convert (integer_type_node,
4410 ffecom_expr (arg2)));
4412 case FFEINTRIN_impRSHIFT:
4413 return ffecom_2 (RSHIFT_EXPR, tree_type,
4415 convert (integer_type_node,
4416 ffecom_expr (arg2)));
4418 case FFEINTRIN_impNOT:
4419 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4421 case FFEINTRIN_impBIT_SIZE:
4422 return convert (tree_type, TYPE_SIZE (arg1_type));
4424 case FFEINTRIN_impBTEST:
4426 ffetargetLogical1 target_true;
4427 ffetargetLogical1 target_false;
4431 ffetarget_logical1 (&target_true, TRUE);
4432 ffetarget_logical1 (&target_false, FALSE);
4433 if (target_true == 1)
4434 true_tree = convert (tree_type, integer_one_node);
4436 true_tree = convert (tree_type, build_int_2 (target_true, 0));
4437 if (target_false == 0)
4438 false_tree = convert (tree_type, integer_zero_node);
4440 false_tree = convert (tree_type, build_int_2 (target_false, 0));
4443 ffecom_3 (COND_EXPR, tree_type,
4445 (ffecom_2 (EQ_EXPR, integer_type_node,
4446 ffecom_2 (BIT_AND_EXPR, arg1_type,
4448 ffecom_2 (LSHIFT_EXPR, arg1_type,
4451 convert (integer_type_node,
4452 ffecom_expr (arg2)))),
4454 integer_zero_node))),
4459 case FFEINTRIN_impIBCLR:
4461 ffecom_2 (BIT_AND_EXPR, tree_type,
4463 ffecom_1 (BIT_NOT_EXPR, tree_type,
4464 ffecom_2 (LSHIFT_EXPR, tree_type,
4467 convert (integer_type_node,
4468 ffecom_expr (arg2)))));
4470 case FFEINTRIN_impIBITS:
4472 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4473 ffecom_expr (arg3)));
4475 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4478 = ffecom_2 (BIT_AND_EXPR, tree_type,
4479 ffecom_2 (RSHIFT_EXPR, tree_type,
4481 convert (integer_type_node,
4482 ffecom_expr (arg2))),
4484 ffecom_2 (RSHIFT_EXPR, uns_type,
4485 ffecom_1 (BIT_NOT_EXPR,
4488 integer_zero_node)),
4489 ffecom_2 (MINUS_EXPR,
4491 TYPE_SIZE (uns_type),
4493 /* Fix up, because the RSHIFT_EXPR above can't shift over TYPE_SIZE. */
4495 = ffecom_3 (COND_EXPR, tree_type,
4497 (ffecom_2 (NE_EXPR, integer_type_node,
4499 integer_zero_node)),
4501 convert (tree_type, integer_zero_node));
4505 case FFEINTRIN_impIBSET:
4507 ffecom_2 (BIT_IOR_EXPR, tree_type,
4509 ffecom_2 (LSHIFT_EXPR, tree_type,
4510 convert (tree_type, integer_one_node),
4511 convert (integer_type_node,
4512 ffecom_expr (arg2))));
4514 case FFEINTRIN_impISHFT:
4516 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4517 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4518 ffecom_expr (arg2)));
4520 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4523 = ffecom_3 (COND_EXPR, tree_type,
4525 (ffecom_2 (GE_EXPR, integer_type_node,
4527 integer_zero_node)),
4528 ffecom_2 (LSHIFT_EXPR, tree_type,
4532 ffecom_2 (RSHIFT_EXPR, uns_type,
4533 convert (uns_type, arg1_tree),
4534 ffecom_1 (NEGATE_EXPR,
4537 /* Fix up, because {L|R}SHIFT_EXPR don't go over TYPE_SIZE bounds. */
4539 = ffecom_3 (COND_EXPR, tree_type,
4541 (ffecom_2 (NE_EXPR, integer_type_node,
4545 TYPE_SIZE (uns_type))),
4547 convert (tree_type, integer_zero_node));
4548 /* Make sure SAVE_EXPRs get referenced early enough. */
4550 = ffecom_2 (COMPOUND_EXPR, tree_type,
4551 convert (void_type_node, arg1_tree),
4552 ffecom_2 (COMPOUND_EXPR, tree_type,
4553 convert (void_type_node, arg2_tree),
4558 case FFEINTRIN_impISHFTC:
4560 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4561 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4562 ffecom_expr (arg2)));
4563 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4564 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4570 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4573 = ffecom_2 (LSHIFT_EXPR, tree_type,
4574 ffecom_1 (BIT_NOT_EXPR, tree_type,
4575 convert (tree_type, integer_zero_node)),
4577 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
4579 = ffecom_3 (COND_EXPR, tree_type,
4581 (ffecom_2 (NE_EXPR, integer_type_node,
4583 TYPE_SIZE (uns_type))),
4585 convert (tree_type, integer_zero_node));
4586 mask_arg1 = ffecom_save_tree (mask_arg1);
4588 = ffecom_2 (BIT_AND_EXPR, tree_type,
4590 ffecom_1 (BIT_NOT_EXPR, tree_type,
4592 masked_arg1 = ffecom_save_tree (masked_arg1);
4594 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4596 ffecom_2 (RSHIFT_EXPR, uns_type,
4597 convert (uns_type, masked_arg1),
4598 ffecom_1 (NEGATE_EXPR,
4601 ffecom_2 (LSHIFT_EXPR, tree_type,
4603 ffecom_2 (PLUS_EXPR, integer_type_node,
4607 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4608 ffecom_2 (LSHIFT_EXPR, tree_type,
4612 ffecom_2 (RSHIFT_EXPR, uns_type,
4613 convert (uns_type, masked_arg1),
4614 ffecom_2 (MINUS_EXPR,
4619 = ffecom_3 (COND_EXPR, tree_type,
4621 (ffecom_2 (LT_EXPR, integer_type_node,
4623 integer_zero_node)),
4627 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4628 ffecom_2 (BIT_AND_EXPR, tree_type,
4631 ffecom_2 (BIT_AND_EXPR, tree_type,
4632 ffecom_1 (BIT_NOT_EXPR, tree_type,
4636 = ffecom_3 (COND_EXPR, tree_type,
4638 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4639 ffecom_2 (EQ_EXPR, integer_type_node,
4644 ffecom_2 (EQ_EXPR, integer_type_node,
4646 integer_zero_node))),
4649 /* Make sure SAVE_EXPRs get referenced early enough. */
4651 = ffecom_2 (COMPOUND_EXPR, tree_type,
4652 convert (void_type_node, arg1_tree),
4653 ffecom_2 (COMPOUND_EXPR, tree_type,
4654 convert (void_type_node, arg2_tree),
4655 ffecom_2 (COMPOUND_EXPR, tree_type,
4656 convert (void_type_node,
4658 ffecom_2 (COMPOUND_EXPR, tree_type,
4659 convert (void_type_node,
4663 = ffecom_2 (COMPOUND_EXPR, tree_type,
4664 convert (void_type_node,
4670 case FFEINTRIN_impLOC:
4672 tree arg1_tree = ffecom_expr (arg1);
4675 = convert (tree_type,
4676 ffecom_1 (ADDR_EXPR,
4677 build_pointer_type (TREE_TYPE (arg1_tree)),
4682 case FFEINTRIN_impMVBITS:
4687 ffebld arg4 = ffebld_head (ffebld_trail (list));
4690 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4694 tree arg5_plus_arg3;
4696 arg2_tree = convert (integer_type_node,
4697 ffecom_expr (arg2));
4698 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4699 ffecom_expr (arg3)));
4700 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
4701 arg4_type = TREE_TYPE (arg4_tree);
4703 arg1_tree = ffecom_save_tree (convert (arg4_type,
4704 ffecom_expr (arg1)));
4706 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4707 ffecom_expr (arg5)));
4710 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4711 ffecom_2 (BIT_AND_EXPR, arg4_type,
4712 ffecom_2 (RSHIFT_EXPR, arg4_type,
4715 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4716 ffecom_2 (LSHIFT_EXPR, arg4_type,
4717 ffecom_1 (BIT_NOT_EXPR,
4721 integer_zero_node)),
4725 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4729 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4730 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4732 integer_zero_node)),
4734 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
4736 = ffecom_3 (COND_EXPR, arg4_type,
4738 (ffecom_2 (NE_EXPR, integer_type_node,
4740 convert (TREE_TYPE (arg5_plus_arg3),
4741 TYPE_SIZE (arg4_type)))),
4743 convert (arg4_type, integer_zero_node));
4745 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4747 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4749 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4750 ffecom_2 (LSHIFT_EXPR, arg4_type,
4751 ffecom_1 (BIT_NOT_EXPR,
4755 integer_zero_node)),
4758 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4761 /* Fix up (twice), because LSHIFT_EXPR above
4762 can't shift over TYPE_SIZE. */
4764 = ffecom_3 (COND_EXPR, arg4_type,
4766 (ffecom_2 (NE_EXPR, integer_type_node,
4768 convert (TREE_TYPE (arg3_tree),
4769 integer_zero_node))),
4773 = ffecom_3 (COND_EXPR, arg4_type,
4775 (ffecom_2 (NE_EXPR, integer_type_node,
4777 convert (TREE_TYPE (arg3_tree),
4778 TYPE_SIZE (arg4_type)))),
4782 = ffecom_2s (MODIFY_EXPR, void_type_node,
4785 /* Make sure SAVE_EXPRs get referenced early enough. */
4787 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4789 ffecom_2 (COMPOUND_EXPR, void_type_node,
4791 ffecom_2 (COMPOUND_EXPR, void_type_node,
4793 ffecom_2 (COMPOUND_EXPR, void_type_node,
4797 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4804 case FFEINTRIN_impDERF:
4805 case FFEINTRIN_impERF:
4806 case FFEINTRIN_impDERFC:
4807 case FFEINTRIN_impERFC:
4810 case FFEINTRIN_impIARGC:
4811 /* extern int xargc; i__1 = xargc - 1; */
4812 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4814 convert (TREE_TYPE (ffecom_tree_xargc_),
4818 case FFEINTRIN_impSIGNAL_func:
4819 case FFEINTRIN_impSIGNAL_subr:
4825 arg1_tree = convert (ffecom_f2c_integer_type_node,
4826 ffecom_expr (arg1));
4827 arg1_tree = ffecom_1 (ADDR_EXPR,
4828 build_pointer_type (TREE_TYPE (arg1_tree)),
4831 /* Pass procedure as a pointer to it, anything else by value. */
4832 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4833 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4835 arg2_tree = ffecom_ptr_to_expr (arg2);
4836 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4840 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4842 arg3_tree = NULL_TREE;
4844 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4845 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4846 TREE_CHAIN (arg1_tree) = arg2_tree;
4849 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4850 ffecom_gfrt_kindtype (gfrt),
4852 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4856 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4857 ffebld_nonter_hook (expr));
4859 if (arg3_tree != NULL_TREE)
4861 = ffecom_modify (NULL_TREE, arg3_tree,
4862 convert (TREE_TYPE (arg3_tree),
4867 case FFEINTRIN_impALARM:
4873 arg1_tree = convert (ffecom_f2c_integer_type_node,
4874 ffecom_expr (arg1));
4875 arg1_tree = ffecom_1 (ADDR_EXPR,
4876 build_pointer_type (TREE_TYPE (arg1_tree)),
4879 /* Pass procedure as a pointer to it, anything else by value. */
4880 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4881 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4883 arg2_tree = ffecom_ptr_to_expr (arg2);
4884 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4888 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4890 arg3_tree = NULL_TREE;
4892 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4893 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4894 TREE_CHAIN (arg1_tree) = arg2_tree;
4897 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4898 ffecom_gfrt_kindtype (gfrt),
4902 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4903 ffebld_nonter_hook (expr));
4905 if (arg3_tree != NULL_TREE)
4907 = ffecom_modify (NULL_TREE, arg3_tree,
4908 convert (TREE_TYPE (arg3_tree),
4913 case FFEINTRIN_impCHDIR_subr:
4914 case FFEINTRIN_impFDATE_subr:
4915 case FFEINTRIN_impFGET_subr:
4916 case FFEINTRIN_impFPUT_subr:
4917 case FFEINTRIN_impGETCWD_subr:
4918 case FFEINTRIN_impHOSTNM_subr:
4919 case FFEINTRIN_impSYSTEM_subr:
4920 case FFEINTRIN_impUNLINK_subr:
4922 tree arg1_len = integer_zero_node;
4926 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4929 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
4931 arg2_tree = NULL_TREE;
4933 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4934 arg1_len = build_tree_list (NULL_TREE, arg1_len);
4935 TREE_CHAIN (arg1_tree) = arg1_len;
4938 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4939 ffecom_gfrt_kindtype (gfrt),
4943 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4944 ffebld_nonter_hook (expr));
4946 if (arg2_tree != NULL_TREE)
4948 = ffecom_modify (NULL_TREE, arg2_tree,
4949 convert (TREE_TYPE (arg2_tree),
4954 case FFEINTRIN_impEXIT:
4958 expr_tree = build_tree_list (NULL_TREE,
4959 ffecom_1 (ADDR_EXPR,
4961 (ffecom_integer_type_node),
4962 integer_zero_node));
4965 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4966 ffecom_gfrt_kindtype (gfrt),
4970 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4971 ffebld_nonter_hook (expr));
4973 case FFEINTRIN_impFLUSH:
4975 gfrt = FFECOM_gfrtFLUSH;
4977 gfrt = FFECOM_gfrtFLUSH1;
4980 case FFEINTRIN_impCHMOD_subr:
4981 case FFEINTRIN_impLINK_subr:
4982 case FFEINTRIN_impRENAME_subr:
4983 case FFEINTRIN_impSYMLNK_subr:
4985 tree arg1_len = integer_zero_node;
4987 tree arg2_len = integer_zero_node;
4991 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4992 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
4994 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4996 arg3_tree = NULL_TREE;
4998 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4999 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5000 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5001 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5002 TREE_CHAIN (arg1_tree) = arg2_tree;
5003 TREE_CHAIN (arg2_tree) = arg1_len;
5004 TREE_CHAIN (arg1_len) = arg2_len;
5005 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5006 ffecom_gfrt_kindtype (gfrt),
5010 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5011 ffebld_nonter_hook (expr));
5012 if (arg3_tree != NULL_TREE)
5013 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5014 convert (TREE_TYPE (arg3_tree),
5019 case FFEINTRIN_impLSTAT_subr:
5020 case FFEINTRIN_impSTAT_subr:
5022 tree arg1_len = integer_zero_node;
5027 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5029 arg2_tree = ffecom_ptr_to_expr (arg2);
5032 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5034 arg3_tree = NULL_TREE;
5036 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5037 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5038 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5039 TREE_CHAIN (arg1_tree) = arg2_tree;
5040 TREE_CHAIN (arg2_tree) = arg1_len;
5041 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5042 ffecom_gfrt_kindtype (gfrt),
5046 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5047 ffebld_nonter_hook (expr));
5048 if (arg3_tree != NULL_TREE)
5049 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5050 convert (TREE_TYPE (arg3_tree),
5055 case FFEINTRIN_impFGETC_subr:
5056 case FFEINTRIN_impFPUTC_subr:
5060 tree arg2_len = integer_zero_node;
5063 arg1_tree = convert (ffecom_f2c_integer_type_node,
5064 ffecom_expr (arg1));
5065 arg1_tree = ffecom_1 (ADDR_EXPR,
5066 build_pointer_type (TREE_TYPE (arg1_tree)),
5069 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5071 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5073 arg3_tree = NULL_TREE;
5075 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5076 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5077 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5078 TREE_CHAIN (arg1_tree) = arg2_tree;
5079 TREE_CHAIN (arg2_tree) = arg2_len;
5081 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5082 ffecom_gfrt_kindtype (gfrt),
5086 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5087 ffebld_nonter_hook (expr));
5088 if (arg3_tree != NULL_TREE)
5089 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5090 convert (TREE_TYPE (arg3_tree),
5095 case FFEINTRIN_impFSTAT_subr:
5101 arg1_tree = convert (ffecom_f2c_integer_type_node,
5102 ffecom_expr (arg1));
5103 arg1_tree = ffecom_1 (ADDR_EXPR,
5104 build_pointer_type (TREE_TYPE (arg1_tree)),
5107 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
5108 ffecom_ptr_to_expr (arg2));
5111 arg3_tree = NULL_TREE;
5113 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5115 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5116 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5117 TREE_CHAIN (arg1_tree) = arg2_tree;
5118 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5119 ffecom_gfrt_kindtype (gfrt),
5123 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5124 ffebld_nonter_hook (expr));
5125 if (arg3_tree != NULL_TREE) {
5126 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5127 convert (TREE_TYPE (arg3_tree),
5133 case FFEINTRIN_impKILL_subr:
5139 arg1_tree = convert (ffecom_f2c_integer_type_node,
5140 ffecom_expr (arg1));
5141 arg1_tree = ffecom_1 (ADDR_EXPR,
5142 build_pointer_type (TREE_TYPE (arg1_tree)),
5145 arg2_tree = convert (ffecom_f2c_integer_type_node,
5146 ffecom_expr (arg2));
5147 arg2_tree = ffecom_1 (ADDR_EXPR,
5148 build_pointer_type (TREE_TYPE (arg2_tree)),
5152 arg3_tree = NULL_TREE;
5154 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5156 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5157 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5158 TREE_CHAIN (arg1_tree) = arg2_tree;
5159 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5160 ffecom_gfrt_kindtype (gfrt),
5164 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5165 ffebld_nonter_hook (expr));
5166 if (arg3_tree != NULL_TREE) {
5167 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5168 convert (TREE_TYPE (arg3_tree),
5174 case FFEINTRIN_impCTIME_subr:
5175 case FFEINTRIN_impTTYNAM_subr:
5177 tree arg1_len = integer_zero_node;
5181 arg1_tree = ffecom_arg_ptr_to_expr (arg2, &arg1_len);
5183 arg2_tree = convert (((codegen_imp == FFEINTRIN_impCTIME_subr) ?
5184 ffecom_f2c_longint_type_node :
5185 ffecom_f2c_integer_type_node),
5186 ffecom_expr (arg1));
5187 arg2_tree = ffecom_1 (ADDR_EXPR,
5188 build_pointer_type (TREE_TYPE (arg2_tree)),
5191 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5192 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5193 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5194 TREE_CHAIN (arg1_len) = arg2_tree;
5195 TREE_CHAIN (arg1_tree) = arg1_len;
5198 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5199 ffecom_gfrt_kindtype (gfrt),
5203 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5204 ffebld_nonter_hook (expr));
5205 TREE_SIDE_EFFECTS (expr_tree) = 1;
5209 case FFEINTRIN_impIRAND:
5210 case FFEINTRIN_impRAND:
5211 /* Arg defaults to 0 (normal random case) */
5216 arg1_tree = ffecom_integer_zero_node;
5218 arg1_tree = ffecom_expr (arg1);
5219 arg1_tree = convert (ffecom_f2c_integer_type_node,
5221 arg1_tree = ffecom_1 (ADDR_EXPR,
5222 build_pointer_type (TREE_TYPE (arg1_tree)),
5224 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5226 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5227 ffecom_gfrt_kindtype (gfrt),
5229 ((codegen_imp == FFEINTRIN_impIRAND) ?
5230 ffecom_f2c_integer_type_node :
5231 ffecom_f2c_real_type_node),
5233 dest_tree, dest, dest_used,
5235 ffebld_nonter_hook (expr));
5239 case FFEINTRIN_impFTELL_subr:
5240 case FFEINTRIN_impUMASK_subr:
5245 arg1_tree = convert (ffecom_f2c_integer_type_node,
5246 ffecom_expr (arg1));
5247 arg1_tree = ffecom_1 (ADDR_EXPR,
5248 build_pointer_type (TREE_TYPE (arg1_tree)),
5252 arg2_tree = NULL_TREE;
5254 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5256 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5257 ffecom_gfrt_kindtype (gfrt),
5260 build_tree_list (NULL_TREE, arg1_tree),
5261 NULL_TREE, NULL, NULL, NULL_TREE,
5263 ffebld_nonter_hook (expr));
5264 if (arg2_tree != NULL_TREE) {
5265 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5266 convert (TREE_TYPE (arg2_tree),
5272 case FFEINTRIN_impCPU_TIME:
5273 case FFEINTRIN_impSECOND_subr:
5277 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5280 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5281 ffecom_gfrt_kindtype (gfrt),
5285 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5286 ffebld_nonter_hook (expr));
5289 = ffecom_modify (NULL_TREE, arg1_tree,
5290 convert (TREE_TYPE (arg1_tree),
5295 case FFEINTRIN_impDTIME_subr:
5296 case FFEINTRIN_impETIME_subr:
5301 result_tree = ffecom_expr_w (NULL_TREE, arg2);
5303 arg1_tree = ffecom_ptr_to_expr (arg1);
5305 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5306 ffecom_gfrt_kindtype (gfrt),
5309 build_tree_list (NULL_TREE, arg1_tree),
5310 NULL_TREE, NULL, NULL, NULL_TREE,
5312 ffebld_nonter_hook (expr));
5313 expr_tree = ffecom_modify (NULL_TREE, result_tree,
5314 convert (TREE_TYPE (result_tree),
5319 /* Straightforward calls of libf2c routines: */
5320 case FFEINTRIN_impABORT:
5321 case FFEINTRIN_impACCESS:
5322 case FFEINTRIN_impBESJ0:
5323 case FFEINTRIN_impBESJ1:
5324 case FFEINTRIN_impBESJN:
5325 case FFEINTRIN_impBESY0:
5326 case FFEINTRIN_impBESY1:
5327 case FFEINTRIN_impBESYN:
5328 case FFEINTRIN_impCHDIR_func:
5329 case FFEINTRIN_impCHMOD_func:
5330 case FFEINTRIN_impDATE:
5331 case FFEINTRIN_impDATE_AND_TIME:
5332 case FFEINTRIN_impDBESJ0:
5333 case FFEINTRIN_impDBESJ1:
5334 case FFEINTRIN_impDBESJN:
5335 case FFEINTRIN_impDBESY0:
5336 case FFEINTRIN_impDBESY1:
5337 case FFEINTRIN_impDBESYN:
5338 case FFEINTRIN_impDTIME_func:
5339 case FFEINTRIN_impETIME_func:
5340 case FFEINTRIN_impFGETC_func:
5341 case FFEINTRIN_impFGET_func:
5342 case FFEINTRIN_impFNUM:
5343 case FFEINTRIN_impFPUTC_func:
5344 case FFEINTRIN_impFPUT_func:
5345 case FFEINTRIN_impFSEEK:
5346 case FFEINTRIN_impFSTAT_func:
5347 case FFEINTRIN_impFTELL_func:
5348 case FFEINTRIN_impGERROR:
5349 case FFEINTRIN_impGETARG:
5350 case FFEINTRIN_impGETCWD_func:
5351 case FFEINTRIN_impGETENV:
5352 case FFEINTRIN_impGETGID:
5353 case FFEINTRIN_impGETLOG:
5354 case FFEINTRIN_impGETPID:
5355 case FFEINTRIN_impGETUID:
5356 case FFEINTRIN_impGMTIME:
5357 case FFEINTRIN_impHOSTNM_func:
5358 case FFEINTRIN_impIDATE_unix:
5359 case FFEINTRIN_impIDATE_vxt:
5360 case FFEINTRIN_impIERRNO:
5361 case FFEINTRIN_impISATTY:
5362 case FFEINTRIN_impITIME:
5363 case FFEINTRIN_impKILL_func:
5364 case FFEINTRIN_impLINK_func:
5365 case FFEINTRIN_impLNBLNK:
5366 case FFEINTRIN_impLSTAT_func:
5367 case FFEINTRIN_impLTIME:
5368 case FFEINTRIN_impMCLOCK8:
5369 case FFEINTRIN_impMCLOCK:
5370 case FFEINTRIN_impPERROR:
5371 case FFEINTRIN_impRENAME_func:
5372 case FFEINTRIN_impSECNDS:
5373 case FFEINTRIN_impSECOND_func:
5374 case FFEINTRIN_impSLEEP:
5375 case FFEINTRIN_impSRAND:
5376 case FFEINTRIN_impSTAT_func:
5377 case FFEINTRIN_impSYMLNK_func:
5378 case FFEINTRIN_impSYSTEM_CLOCK:
5379 case FFEINTRIN_impSYSTEM_func:
5380 case FFEINTRIN_impTIME8:
5381 case FFEINTRIN_impTIME_unix:
5382 case FFEINTRIN_impTIME_vxt:
5383 case FFEINTRIN_impUMASK_func:
5384 case FFEINTRIN_impUNLINK_func:
5387 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5388 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5389 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5390 case FFEINTRIN_impNONE:
5391 case FFEINTRIN_imp: /* Hush up gcc warning. */
5392 fprintf (stderr, "No %s implementation.\n",
5393 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5394 assert ("unimplemented intrinsic" == NULL);
5395 return error_mark_node;
5398 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5400 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5401 ffebld_right (expr));
5403 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5404 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5406 expr_tree, dest_tree, dest, dest_used,
5408 ffebld_nonter_hook (expr));
5410 /* See bottom of this file for f2c transforms used to determine
5411 many of the above implementations. The info seems to confuse
5412 Emacs's C mode indentation, which is why it's been moved to
5413 the bottom of this source file. */
5416 /* For power (exponentiation) where right-hand operand is type INTEGER,
5417 generate in-line code to do it the fast way (which, if the operand
5418 is a constant, might just mean a series of multiplies). */
5421 ffecom_expr_power_integer_ (ffebld expr)
5423 tree l = ffecom_expr (ffebld_left (expr));
5424 tree r = ffecom_expr (ffebld_right (expr));
5425 tree ltype = TREE_TYPE (l);
5426 tree rtype = TREE_TYPE (r);
5427 tree result = NULL_TREE;
5429 if (l == error_mark_node
5430 || r == error_mark_node)
5431 return error_mark_node;
5433 if (TREE_CODE (r) == INTEGER_CST)
5435 int sgn = tree_int_cst_sgn (r);
5438 return convert (ltype, integer_one_node);
5440 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5443 /* Reciprocal of integer is either 0, -1, or 1, so after
5444 calculating that (which we leave to the back end to do
5445 or not do optimally), don't bother with any multiplying. */
5447 result = ffecom_tree_divide_ (ltype,
5448 convert (ltype, integer_one_node),
5450 NULL_TREE, NULL, NULL, NULL_TREE);
5451 r = ffecom_1 (NEGATE_EXPR,
5454 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5455 result = ffecom_1 (ABS_EXPR, rtype,
5459 /* Generate appropriate series of multiplies, preceded
5460 by divide if the exponent is negative. */
5466 l = ffecom_tree_divide_ (ltype,
5467 convert (ltype, integer_one_node),
5469 NULL_TREE, NULL, NULL,
5470 ffebld_nonter_hook (expr));
5471 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5472 assert (TREE_CODE (r) == INTEGER_CST);
5474 if (tree_int_cst_sgn (r) < 0)
5475 { /* The "most negative" number. */
5476 r = ffecom_1 (NEGATE_EXPR, rtype,
5477 ffecom_2 (RSHIFT_EXPR, rtype,
5481 l = ffecom_2 (MULT_EXPR, ltype,
5489 if (TREE_INT_CST_LOW (r) & 1)
5491 if (result == NULL_TREE)
5494 result = ffecom_2 (MULT_EXPR, ltype,
5499 r = ffecom_2 (RSHIFT_EXPR, rtype,
5502 if (integer_zerop (r))
5504 assert (TREE_CODE (r) == INTEGER_CST);
5507 l = ffecom_2 (MULT_EXPR, ltype,
5514 /* Though rhs isn't a constant, in-line code cannot be expanded
5515 while transforming dummies
5516 because the back end cannot be easily convinced to generate
5517 stores (MODIFY_EXPR), handle temporaries, and so on before
5518 all the appropriate rtx's have been generated for things like
5519 dummy args referenced in rhs -- which doesn't happen until
5520 store_parm_decls() is called (expand_function_start, I believe,
5521 does the actual rtx-stuffing of PARM_DECLs).
5523 So, in this case, let the caller generate the call to the
5524 run-time-library function to evaluate the power for us. */
5526 if (ffecom_transform_only_dummies_)
5529 /* Right-hand operand not a constant, expand in-line code to figure
5530 out how to do the multiplies, &c.
5532 The returned expression is expressed this way in GNU C, where l and
5535 ({ typeof (r) rtmp = r;
5536 typeof (l) ltmp = l;
5543 if ((basetypeof (l) == basetypeof (int))
5546 result = ((typeof (l)) 1) / ltmp;
5547 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5553 if ((basetypeof (l) != basetypeof (int))
5556 ltmp = ((typeof (l)) 1) / ltmp;
5560 rtmp = -(rtmp >> 1);
5568 if ((rtmp >>= 1) == 0)
5577 Note that some of the above is compile-time collapsable, such as
5578 the first part of the if statements that checks the base type of
5579 l against int. The if statements are phrased that way to suggest
5580 an easy way to generate the if/else constructs here, knowing that
5581 the back end should (and probably does) eliminate the resulting
5582 dead code (either the int case or the non-int case), something
5583 it couldn't do without the redundant phrasing, requiring explicit
5584 dead-code elimination here, which would be kind of difficult to
5591 tree basetypeof_l_is_int;
5596 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5598 se = expand_start_stmt_expr ();
5600 ffecom_start_compstmt ();
5603 rtmp = ffecom_make_tempvar ("power_r", rtype,
5604 FFETARGET_charactersizeNONE, -1);
5605 ltmp = ffecom_make_tempvar ("power_l", ltype,
5606 FFETARGET_charactersizeNONE, -1);
5607 result = ffecom_make_tempvar ("power_res", ltype,
5608 FFETARGET_charactersizeNONE, -1);
5609 if (TREE_CODE (ltype) == COMPLEX_TYPE
5610 || TREE_CODE (ltype) == RECORD_TYPE)
5611 divide = ffecom_make_tempvar ("power_div", ltype,
5612 FFETARGET_charactersizeNONE, -1);
5619 hook = ffebld_nonter_hook (expr);
5621 assert (TREE_CODE (hook) == TREE_VEC);
5622 assert (TREE_VEC_LENGTH (hook) == 4);
5623 rtmp = TREE_VEC_ELT (hook, 0);
5624 ltmp = TREE_VEC_ELT (hook, 1);
5625 result = TREE_VEC_ELT (hook, 2);
5626 divide = TREE_VEC_ELT (hook, 3);
5627 if (TREE_CODE (ltype) == COMPLEX_TYPE
5628 || TREE_CODE (ltype) == RECORD_TYPE)
5635 expand_expr_stmt (ffecom_modify (void_type_node,
5638 expand_expr_stmt (ffecom_modify (void_type_node,
5641 expand_start_cond (ffecom_truth_value
5642 (ffecom_2 (EQ_EXPR, integer_type_node,
5644 convert (rtype, integer_zero_node))),
5646 expand_expr_stmt (ffecom_modify (void_type_node,
5648 convert (ltype, integer_one_node)));
5649 expand_start_else ();
5650 if (! integer_zerop (basetypeof_l_is_int))
5652 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5655 integer_zero_node)),
5657 expand_expr_stmt (ffecom_modify (void_type_node,
5661 convert (ltype, integer_one_node),
5663 NULL_TREE, NULL, NULL,
5665 expand_start_cond (ffecom_truth_value
5666 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5667 ffecom_2 (LT_EXPR, integer_type_node,
5670 integer_zero_node)),
5671 ffecom_2 (EQ_EXPR, integer_type_node,
5672 ffecom_2 (BIT_AND_EXPR,
5674 ffecom_1 (NEGATE_EXPR,
5680 integer_zero_node)))),
5682 expand_expr_stmt (ffecom_modify (void_type_node,
5684 ffecom_1 (NEGATE_EXPR,
5688 expand_start_else ();
5690 expand_expr_stmt (ffecom_modify (void_type_node,
5692 convert (ltype, integer_one_node)));
5693 expand_start_cond (ffecom_truth_value
5694 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5695 ffecom_truth_value_invert
5696 (basetypeof_l_is_int),
5697 ffecom_2 (LT_EXPR, integer_type_node,
5700 integer_zero_node)))),
5702 expand_expr_stmt (ffecom_modify (void_type_node,
5706 convert (ltype, integer_one_node),
5708 NULL_TREE, NULL, NULL,
5710 expand_expr_stmt (ffecom_modify (void_type_node,
5712 ffecom_1 (NEGATE_EXPR, rtype,
5714 expand_start_cond (ffecom_truth_value
5715 (ffecom_2 (LT_EXPR, integer_type_node,
5717 convert (rtype, integer_zero_node))),
5719 expand_expr_stmt (ffecom_modify (void_type_node,
5721 ffecom_1 (NEGATE_EXPR, rtype,
5722 ffecom_2 (RSHIFT_EXPR,
5725 integer_one_node))));
5726 expand_expr_stmt (ffecom_modify (void_type_node,
5728 ffecom_2 (MULT_EXPR, ltype,
5733 expand_start_loop (1);
5734 expand_start_cond (ffecom_truth_value
5735 (ffecom_2 (BIT_AND_EXPR, rtype,
5737 convert (rtype, integer_one_node))),
5739 expand_expr_stmt (ffecom_modify (void_type_node,
5741 ffecom_2 (MULT_EXPR, ltype,
5745 expand_exit_loop_if_false (NULL,
5747 (ffecom_modify (rtype,
5749 ffecom_2 (RSHIFT_EXPR,
5752 integer_one_node))));
5753 expand_expr_stmt (ffecom_modify (void_type_node,
5755 ffecom_2 (MULT_EXPR, ltype,
5760 if (!integer_zerop (basetypeof_l_is_int))
5762 expand_expr_stmt (result);
5764 t = ffecom_end_compstmt ();
5766 result = expand_end_stmt_expr (se);
5768 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5770 if (TREE_CODE (t) == BLOCK)
5772 /* Make a BIND_EXPR for the BLOCK already made. */
5773 result = build (BIND_EXPR, TREE_TYPE (result),
5774 NULL_TREE, result, t);
5775 /* Remove the block from the tree at this point.
5776 It gets put back at the proper place
5777 when the BIND_EXPR is expanded. */
5787 /* ffecom_expr_transform_ -- Transform symbols in expr
5789 ffebld expr; // FFE expression.
5790 ffecom_expr_transform_ (expr);
5792 Recursive descent on expr while transforming any untransformed SYMTERs. */
5795 ffecom_expr_transform_ (ffebld expr)
5805 switch (ffebld_op (expr))
5807 case FFEBLD_opSYMTER:
5808 s = ffebld_symter (expr);
5809 t = ffesymbol_hook (s).decl_tree;
5810 if ((t == NULL_TREE)
5811 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5812 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5813 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5815 s = ffecom_sym_transform_ (s);
5816 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5819 break; /* Ok if (t == NULL) here. */
5822 ffecom_expr_transform_ (ffebld_head (expr));
5823 expr = ffebld_trail (expr);
5824 goto tail_recurse; /* :::::::::::::::::::: */
5830 switch (ffebld_arity (expr))
5833 ffecom_expr_transform_ (ffebld_left (expr));
5834 expr = ffebld_right (expr);
5835 goto tail_recurse; /* :::::::::::::::::::: */
5838 expr = ffebld_left (expr);
5839 goto tail_recurse; /* :::::::::::::::::::: */
5848 /* Make a type based on info in live f2c.h file. */
5851 ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5855 case FFECOM_f2ccodeCHAR:
5856 *type = make_signed_type (CHAR_TYPE_SIZE);
5859 case FFECOM_f2ccodeSHORT:
5860 *type = make_signed_type (SHORT_TYPE_SIZE);
5863 case FFECOM_f2ccodeINT:
5864 *type = make_signed_type (INT_TYPE_SIZE);
5867 case FFECOM_f2ccodeLONG:
5868 *type = make_signed_type (LONG_TYPE_SIZE);
5871 case FFECOM_f2ccodeLONGLONG:
5872 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
5875 case FFECOM_f2ccodeCHARPTR:
5876 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
5877 ? signed_char_type_node
5878 : unsigned_char_type_node);
5881 case FFECOM_f2ccodeFLOAT:
5882 *type = make_node (REAL_TYPE);
5883 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
5884 layout_type (*type);
5887 case FFECOM_f2ccodeDOUBLE:
5888 *type = make_node (REAL_TYPE);
5889 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
5890 layout_type (*type);
5893 case FFECOM_f2ccodeLONGDOUBLE:
5894 *type = make_node (REAL_TYPE);
5895 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
5896 layout_type (*type);
5899 case FFECOM_f2ccodeTWOREALS:
5900 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
5903 case FFECOM_f2ccodeTWODOUBLEREALS:
5904 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
5908 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
5909 *type = error_mark_node;
5913 pushdecl (build_decl (TYPE_DECL,
5914 ffecom_get_invented_identifier ("__g77_f2c_%s", name),
5918 /* Set the f2c list-directed-I/O code for whatever (integral) type has the
5922 ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
5928 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
5929 if ((t = ffecom_tree_type[bt][j]) != NULL_TREE
5930 && compare_tree_int (TYPE_SIZE (t), size) == 0)
5932 assert (code != -1);
5933 ffecom_f2c_typecode_[bt][j] = code;
5938 /* Finish up globals after doing all program units in file
5940 Need to handle only uninitialized COMMON areas. */
5943 ffecom_finish_global_ (ffeglobal global)
5949 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
5952 if (ffeglobal_common_init (global))
5955 cbt = ffeglobal_hook (global);
5956 if ((cbt == NULL_TREE)
5957 || !ffeglobal_common_have_size (global))
5958 return global; /* No need to make common, never ref'd. */
5960 DECL_EXTERNAL (cbt) = 0;
5962 /* Give the array a size now. */
5964 size = build_int_2 ((ffeglobal_common_size (global)
5965 + ffeglobal_common_pad (global)) - 1,
5968 cbtype = TREE_TYPE (cbt);
5969 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
5972 if (!TREE_TYPE (size))
5973 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
5974 layout_type (cbtype);
5976 cbt = start_decl (cbt, FALSE);
5977 assert (cbt == ffeglobal_hook (global));
5979 finish_decl (cbt, NULL_TREE, FALSE);
5984 /* Finish up any untransformed symbols. */
5987 ffecom_finish_symbol_transform_ (ffesymbol s)
5989 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
5992 /* It's easy to know to transform an untransformed symbol, to make sure
5993 we put out debugging info for it. But COMMON variables, unlike
5994 EQUIVALENCE ones, aren't given declarations in addition to the
5995 tree expressions that specify offsets, because COMMON variables
5996 can be referenced in the outer scope where only dummy arguments
5997 (PARM_DECLs) should really be seen. To be safe, just don't do any
5998 VAR_DECLs for COMMON variables when we transform them for real
5999 use, and therefore we do all the VAR_DECL creating here. */
6001 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
6003 if (ffesymbol_kind (s) != FFEINFO_kindNONE
6004 || (ffesymbol_where (s) != FFEINFO_whereNONE
6005 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
6006 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
6007 /* Not transformed, and not CHARACTER*(*), and not a dummy
6008 argument, which can happen only if the entry point names
6009 it "rides in on" are all invalidated for other reasons. */
6010 s = ffecom_sym_transform_ (s);
6013 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
6014 && (ffesymbol_hook (s).decl_tree != error_mark_node))
6016 /* This isn't working, at least for dbxout. The .s file looks
6017 okay to me (burley), but in gdb 4.9 at least, the variables
6018 appear to reside somewhere outside of the common area, so
6019 it doesn't make sense to mislead anyone by generating the info
6020 on those variables until this is fixed. NOTE: Same problem
6021 with EQUIVALENCE, sadly...see similar #if later. */
6022 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6023 ffesymbol_storage (s));
6029 /* Append underscore(s) to name before calling get_identifier. "us"
6030 is nonzero if the name already contains an underscore and thus
6031 needs two underscores appended. */
6034 ffecom_get_appended_identifier_ (char us, const char *name)
6040 newname = xmalloc ((i = strlen (name)) + 1
6041 + ffe_is_underscoring ()
6043 memcpy (newname, name, i);
6045 newname[i + us] = '_';
6046 newname[i + 1 + us] = '\0';
6047 id = get_identifier (newname);
6054 /* Decide whether to append underscore to name before calling
6058 ffecom_get_external_identifier_ (ffesymbol s)
6061 const char *name = ffesymbol_text (s);
6063 /* If name is a built-in name, just return it as is. */
6065 if (!ffe_is_underscoring ()
6066 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6067 #if FFETARGET_isENFORCED_MAIN_NAME
6068 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
6070 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6072 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6073 return get_identifier (name);
6075 us = ffe_is_second_underscore ()
6076 ? (strchr (name, '_') != NULL)
6079 return ffecom_get_appended_identifier_ (us, name);
6082 /* Decide whether to append underscore to internal name before calling
6085 This is for non-external, top-function-context names only. Transform
6086 identifier so it doesn't conflict with the transformed result
6087 of using a _different_ external name. E.g. if "CALL FOO" is
6088 transformed into "FOO_();", then the variable in "FOO_ = 3"
6089 must be transformed into something that does not conflict, since
6090 these two things should be independent.
6092 The transformation is as follows. If the name does not contain
6093 an underscore, there is no possible conflict, so just return.
6094 If the name does contain an underscore, then transform it just
6095 like we transform an external identifier. */
6098 ffecom_get_identifier_ (const char *name)
6100 /* If name does not contain an underscore, just return it as is. */
6102 if (!ffe_is_underscoring ()
6103 || (strchr (name, '_') == NULL))
6104 return get_identifier (name);
6106 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6110 /* ffecom_gen_sfuncdef_ -- Generate definition of statement function
6113 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6114 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6115 ffesymbol_kindtype(s));
6117 Call after setting up containing function and getting trees for all
6121 ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
6123 ffebld expr = ffesymbol_sfexpr (s);
6127 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6128 static bool recurse = FALSE;
6129 int old_lineno = lineno;
6130 const char *old_input_filename = input_filename;
6132 ffecom_nested_entry_ = s;
6134 /* For now, we don't have a handy pointer to where the sfunc is actually
6135 defined, though that should be easy to add to an ffesymbol. (The
6136 token/where info available might well point to the place where the type
6137 of the sfunc is declared, especially if that precedes the place where
6138 the sfunc itself is defined, which is typically the case.) We should
6139 put out a null pointer rather than point somewhere wrong, but I want to
6140 see how it works at this point. */
6142 input_filename = ffesymbol_where_filename (s);
6143 lineno = ffesymbol_where_filelinenum (s);
6145 /* Pretransform the expression so any newly discovered things belong to the
6146 outer program unit, not to the statement function. */
6148 ffecom_expr_transform_ (expr);
6150 /* Make sure no recursive invocation of this fn (a specific case of failing
6151 to pretransform an sfunc's expression, i.e. where its expression
6152 references another untransformed sfunc) happens. */
6157 push_f_function_context ();
6160 type = void_type_node;
6163 type = ffecom_tree_type[bt][kt];
6164 if (type == NULL_TREE)
6165 type = integer_type_node; /* _sym_exec_transition reports
6169 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6170 build_function_type (type, NULL_TREE),
6171 1, /* nested/inline */
6172 0); /* TREE_PUBLIC */
6174 /* We don't worry about COMPLEX return values here, because this is
6175 entirely internal to our code, and gcc has the ability to return COMPLEX
6176 directly as a value. */
6179 { /* Prepend arg for where result goes. */
6182 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6184 result = ffecom_get_invented_identifier ("__g77_%s", "result");
6186 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6188 type = build_pointer_type (type);
6189 result = build_decl (PARM_DECL, result, type);
6191 push_parm_decl (result);
6194 result = NULL_TREE; /* Not ref'd if !charfunc. */
6196 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
6198 store_parm_decls (0);
6200 ffecom_start_compstmt ();
6206 ffetargetCharacterSize sz = ffesymbol_size (s);
6209 result_length = build_int_2 (sz, 0);
6210 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
6212 ffecom_prepare_let_char_ (sz, expr);
6214 ffecom_prepare_end ();
6216 ffecom_let_char_ (result, result_length, sz, expr);
6217 expand_null_return ();
6221 ffecom_prepare_expr (expr);
6223 ffecom_prepare_end ();
6225 expand_return (ffecom_modify (NULL_TREE,
6226 DECL_RESULT (current_function_decl),
6227 ffecom_expr (expr)));
6231 ffecom_end_compstmt ();
6233 func = current_function_decl;
6234 finish_function (1);
6236 pop_f_function_context ();
6240 lineno = old_lineno;
6241 input_filename = old_input_filename;
6243 ffecom_nested_entry_ = NULL;
6249 ffecom_gfrt_args_ (ffecomGfrt ix)
6251 return ffecom_gfrt_argstring_[ix];
6255 ffecom_gfrt_tree_ (ffecomGfrt ix)
6257 if (ffecom_gfrt_[ix] == NULL_TREE)
6258 ffecom_make_gfrt_ (ix);
6260 return ffecom_1 (ADDR_EXPR,
6261 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6265 /* Return initialize-to-zero expression for this VAR_DECL. */
6267 /* A somewhat evil way to prevent the garbage collector
6268 from collecting 'tree' structures. */
6269 #define NUM_TRACKED_CHUNK 63
6270 static struct tree_ggc_tracker
6272 struct tree_ggc_tracker *next;
6273 tree trees[NUM_TRACKED_CHUNK];
6274 } *tracker_head = NULL;
6277 mark_tracker_head (void *arg)
6279 struct tree_ggc_tracker *head;
6282 for (head = * (struct tree_ggc_tracker **) arg;
6287 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6288 ggc_mark_tree (head->trees[i]);
6293 ffecom_save_tree_forever (tree t)
6296 if (tracker_head != NULL)
6297 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6298 if (tracker_head->trees[i] == NULL)
6300 tracker_head->trees[i] = t;
6305 /* Need to allocate a new block. */
6306 struct tree_ggc_tracker *old_head = tracker_head;
6308 tracker_head = ggc_alloc (sizeof (*tracker_head));
6309 tracker_head->next = old_head;
6310 tracker_head->trees[0] = t;
6311 for (i = 1; i < NUM_TRACKED_CHUNK; i++)
6312 tracker_head->trees[i] = NULL;
6317 ffecom_init_zero_ (tree decl)
6320 int incremental = TREE_STATIC (decl);
6321 tree type = TREE_TYPE (decl);
6325 make_decl_rtl (decl, NULL);
6326 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
6329 if ((TREE_CODE (type) != ARRAY_TYPE)
6330 && (TREE_CODE (type) != RECORD_TYPE)
6331 && (TREE_CODE (type) != UNION_TYPE)
6333 init = convert (type, integer_zero_node);
6334 else if (!incremental)
6336 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
6337 TREE_CONSTANT (init) = 1;
6338 TREE_STATIC (init) = 1;
6342 assemble_zeros (int_size_in_bytes (type));
6343 init = error_mark_node;
6350 ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
6356 switch (ffebld_op (arg))
6358 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6359 if (ffetarget_length_character1
6360 (ffebld_constant_character1
6361 (ffebld_conter (arg))) == 0)
6363 *maybe_tree = integer_zero_node;
6364 return convert (tree_type, integer_zero_node);
6367 *maybe_tree = integer_one_node;
6368 expr_tree = build_int_2 (*ffetarget_text_character1
6369 (ffebld_constant_character1
6370 (ffebld_conter (arg))),
6372 TREE_TYPE (expr_tree) = tree_type;
6375 case FFEBLD_opSYMTER:
6376 case FFEBLD_opARRAYREF:
6377 case FFEBLD_opFUNCREF:
6378 case FFEBLD_opSUBSTR:
6379 ffecom_char_args_ (&expr_tree, &length_tree, arg);
6381 if ((expr_tree == error_mark_node)
6382 || (length_tree == error_mark_node))
6384 *maybe_tree = error_mark_node;
6385 return error_mark_node;
6388 if (integer_zerop (length_tree))
6390 *maybe_tree = integer_zero_node;
6391 return convert (tree_type, integer_zero_node);
6395 = ffecom_1 (INDIRECT_REF,
6396 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6399 = ffecom_2 (ARRAY_REF,
6400 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6403 expr_tree = convert (tree_type, expr_tree);
6405 if (TREE_CODE (length_tree) == INTEGER_CST)
6406 *maybe_tree = integer_one_node;
6407 else /* Must check length at run time. */
6409 = ffecom_truth_value
6410 (ffecom_2 (GT_EXPR, integer_type_node,
6412 ffecom_f2c_ftnlen_zero_node));
6415 case FFEBLD_opPAREN:
6416 case FFEBLD_opCONVERT:
6417 if (ffeinfo_size (ffebld_info (arg)) == 0)
6419 *maybe_tree = integer_zero_node;
6420 return convert (tree_type, integer_zero_node);
6422 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6425 case FFEBLD_opCONCATENATE:
6432 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6434 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6436 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6439 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6447 assert ("bad op in ICHAR" == NULL);
6448 return error_mark_node;
6452 /* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6456 length_arg = ffecom_intrinsic_len_ (expr);
6458 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6459 subexpressions by constructing the appropriate tree for the
6460 length-of-character-text argument in a calling sequence. */
6463 ffecom_intrinsic_len_ (ffebld expr)
6465 ffetargetCharacter1 val;
6468 switch (ffebld_op (expr))
6470 case FFEBLD_opCONTER:
6471 val = ffebld_constant_character1 (ffebld_conter (expr));
6472 length = build_int_2 (ffetarget_length_character1 (val), 0);
6473 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6476 case FFEBLD_opSYMTER:
6478 ffesymbol s = ffebld_symter (expr);
6481 item = ffesymbol_hook (s).decl_tree;
6482 if (item == NULL_TREE)
6484 s = ffecom_sym_transform_ (s);
6485 item = ffesymbol_hook (s).decl_tree;
6487 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6489 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6490 length = ffesymbol_hook (s).length_tree;
6493 length = build_int_2 (ffesymbol_size (s), 0);
6494 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6497 else if (item == error_mark_node)
6498 length = error_mark_node;
6499 else /* FFEINFO_kindFUNCTION: */
6504 case FFEBLD_opARRAYREF:
6505 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6508 case FFEBLD_opSUBSTR:
6512 ffebld thing = ffebld_right (expr);
6516 assert (ffebld_op (thing) == FFEBLD_opITEM);
6517 start = ffebld_head (thing);
6518 thing = ffebld_trail (thing);
6519 assert (ffebld_trail (thing) == NULL);
6520 end = ffebld_head (thing);
6522 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6524 if (length == error_mark_node)
6533 length = convert (ffecom_f2c_ftnlen_type_node,
6539 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6540 ffecom_expr (start));
6542 if (start_tree == error_mark_node)
6544 length = error_mark_node;
6550 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6551 ffecom_f2c_ftnlen_one_node,
6552 ffecom_2 (MINUS_EXPR,
6553 ffecom_f2c_ftnlen_type_node,
6559 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6562 if (end_tree == error_mark_node)
6564 length = error_mark_node;
6568 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6569 ffecom_f2c_ftnlen_one_node,
6570 ffecom_2 (MINUS_EXPR,
6571 ffecom_f2c_ftnlen_type_node,
6572 end_tree, start_tree));
6578 case FFEBLD_opCONCATENATE:
6580 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6581 ffecom_intrinsic_len_ (ffebld_left (expr)),
6582 ffecom_intrinsic_len_ (ffebld_right (expr)));
6585 case FFEBLD_opFUNCREF:
6586 case FFEBLD_opCONVERT:
6587 length = build_int_2 (ffebld_size (expr), 0);
6588 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6592 assert ("bad op for single char arg expr" == NULL);
6593 length = ffecom_f2c_ftnlen_zero_node;
6597 assert (length != NULL_TREE);
6602 /* Handle CHARACTER assignments.
6604 Generates code to do the assignment. Used by ordinary assignment
6605 statement handler ffecom_let_stmt and by statement-function
6606 handler to generate code for a statement function. */
6609 ffecom_let_char_ (tree dest_tree, tree dest_length,
6610 ffetargetCharacterSize dest_size, ffebld source)
6612 ffecomConcatList_ catlist;
6617 if ((dest_tree == error_mark_node)
6618 || (dest_length == error_mark_node))
6621 assert (dest_tree != NULL_TREE);
6622 assert (dest_length != NULL_TREE);
6624 /* Source might be an opCONVERT, which just means it is a different size
6625 than the destination. Since the underlying implementation here handles
6626 that (directly or via the s_copy or s_cat run-time-library functions),
6627 we don't need the "convenience" of an opCONVERT that tells us to
6628 truncate or blank-pad, particularly since the resulting implementation
6629 would probably be slower than otherwise. */
6631 while (ffebld_op (source) == FFEBLD_opCONVERT)
6632 source = ffebld_left (source);
6634 catlist = ffecom_concat_list_new_ (source, dest_size);
6635 switch (ffecom_concat_list_count_ (catlist))
6637 case 0: /* Shouldn't happen, but in case it does... */
6638 ffecom_concat_list_kill_ (catlist);
6639 source_tree = null_pointer_node;
6640 source_length = ffecom_f2c_ftnlen_zero_node;
6641 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6642 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6643 TREE_CHAIN (TREE_CHAIN (expr_tree))
6644 = build_tree_list (NULL_TREE, dest_length);
6645 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6646 = build_tree_list (NULL_TREE, source_length);
6648 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6649 TREE_SIDE_EFFECTS (expr_tree) = 1;
6651 expand_expr_stmt (expr_tree);
6655 case 1: /* The (fairly) easy case. */
6656 ffecom_char_args_ (&source_tree, &source_length,
6657 ffecom_concat_list_expr_ (catlist, 0));
6658 ffecom_concat_list_kill_ (catlist);
6659 assert (source_tree != NULL_TREE);
6660 assert (source_length != NULL_TREE);
6662 if ((source_tree == error_mark_node)
6663 || (source_length == error_mark_node))
6669 = ffecom_1 (INDIRECT_REF,
6670 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6674 = ffecom_2 (ARRAY_REF,
6675 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6680 = ffecom_1 (INDIRECT_REF,
6681 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6685 = ffecom_2 (ARRAY_REF,
6686 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6691 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
6693 expand_expr_stmt (expr_tree);
6698 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6699 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6700 TREE_CHAIN (TREE_CHAIN (expr_tree))
6701 = build_tree_list (NULL_TREE, dest_length);
6702 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6703 = build_tree_list (NULL_TREE, source_length);
6705 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6706 TREE_SIDE_EFFECTS (expr_tree) = 1;
6708 expand_expr_stmt (expr_tree);
6712 default: /* Must actually concatenate things. */
6716 /* Heavy-duty concatenation. */
6719 int count = ffecom_concat_list_count_ (catlist);
6731 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
6732 FFETARGET_charactersizeNONE, count, TRUE);
6733 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
6734 FFETARGET_charactersizeNONE,
6740 hook = ffebld_nonter_hook (source);
6742 assert (TREE_CODE (hook) == TREE_VEC);
6743 assert (TREE_VEC_LENGTH (hook) == 2);
6744 length_array = lengths = TREE_VEC_ELT (hook, 0);
6745 item_array = items = TREE_VEC_ELT (hook, 1);
6749 for (i = 0; i < count; ++i)
6751 ffecom_char_args_ (&citem, &clength,
6752 ffecom_concat_list_expr_ (catlist, i));
6753 if ((citem == error_mark_node)
6754 || (clength == error_mark_node))
6756 ffecom_concat_list_kill_ (catlist);
6761 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6762 ffecom_modify (void_type_node,
6763 ffecom_2 (ARRAY_REF,
6764 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6766 build_int_2 (i, 0)),
6770 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6771 ffecom_modify (void_type_node,
6772 ffecom_2 (ARRAY_REF,
6773 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6775 build_int_2 (i, 0)),
6780 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6781 TREE_CHAIN (expr_tree)
6782 = build_tree_list (NULL_TREE,
6783 ffecom_1 (ADDR_EXPR,
6784 build_pointer_type (TREE_TYPE (items)),
6786 TREE_CHAIN (TREE_CHAIN (expr_tree))
6787 = build_tree_list (NULL_TREE,
6788 ffecom_1 (ADDR_EXPR,
6789 build_pointer_type (TREE_TYPE (lengths)),
6791 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6794 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6795 convert (ffecom_f2c_ftnlen_type_node,
6796 build_int_2 (count, 0))));
6797 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6798 = build_tree_list (NULL_TREE, dest_length);
6800 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6801 TREE_SIDE_EFFECTS (expr_tree) = 1;
6803 expand_expr_stmt (expr_tree);
6806 ffecom_concat_list_kill_ (catlist);
6809 /* ffecom_make_gfrt_ -- Make initial info for run-time routine
6812 ffecom_make_gfrt_(ix);
6814 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6815 for the indicated run-time routine (ix). */
6818 ffecom_make_gfrt_ (ffecomGfrt ix)
6823 switch (ffecom_gfrt_type_[ix])
6825 case FFECOM_rttypeVOID_:
6826 ttype = void_type_node;
6829 case FFECOM_rttypeVOIDSTAR_:
6830 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
6833 case FFECOM_rttypeFTNINT_:
6834 ttype = ffecom_f2c_ftnint_type_node;
6837 case FFECOM_rttypeINTEGER_:
6838 ttype = ffecom_f2c_integer_type_node;
6841 case FFECOM_rttypeLONGINT_:
6842 ttype = ffecom_f2c_longint_type_node;
6845 case FFECOM_rttypeLOGICAL_:
6846 ttype = ffecom_f2c_logical_type_node;
6849 case FFECOM_rttypeREAL_F2C_:
6850 ttype = double_type_node;
6853 case FFECOM_rttypeREAL_GNU_:
6854 ttype = float_type_node;
6857 case FFECOM_rttypeCOMPLEX_F2C_:
6858 ttype = void_type_node;
6861 case FFECOM_rttypeCOMPLEX_GNU_:
6862 ttype = ffecom_f2c_complex_type_node;
6865 case FFECOM_rttypeDOUBLE_:
6866 ttype = double_type_node;
6869 case FFECOM_rttypeDOUBLEREAL_:
6870 ttype = ffecom_f2c_doublereal_type_node;
6873 case FFECOM_rttypeDBLCMPLX_F2C_:
6874 ttype = void_type_node;
6877 case FFECOM_rttypeDBLCMPLX_GNU_:
6878 ttype = ffecom_f2c_doublecomplex_type_node;
6881 case FFECOM_rttypeCHARACTER_:
6882 ttype = void_type_node;
6887 assert ("bad rttype" == NULL);
6891 ttype = build_function_type (ttype, NULL_TREE);
6892 t = build_decl (FUNCTION_DECL,
6893 get_identifier (ffecom_gfrt_name_[ix]),
6895 DECL_EXTERNAL (t) = 1;
6896 TREE_READONLY (t) = ffecom_gfrt_const_[ix] ? 1 : 0;
6897 TREE_PUBLIC (t) = 1;
6898 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
6900 /* Sanity check: A function that's const cannot be volatile. */
6902 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_volatile_[ix] : 1);
6904 /* Sanity check: A function that's const cannot return complex. */
6906 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_complex_[ix] : 1);
6908 t = start_decl (t, TRUE);
6910 finish_decl (t, NULL_TREE, TRUE);
6912 ffecom_gfrt_[ix] = t;
6915 /* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
6918 ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
6920 ffesymbol s = ffestorag_symbol (st);
6922 if (ffesymbol_namelisted (s))
6923 ffecom_member_namelisted_ = TRUE;
6926 /* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
6927 the member so debugger will see it. Otherwise nobody should be
6928 referencing the member. */
6931 ffecom_member_phase2_ (ffestorag mst, ffestorag st)
6939 || ((mt = ffestorag_hook (mst)) == NULL)
6940 || (mt == error_mark_node))
6944 || ((s = ffestorag_symbol (st)) == NULL))
6947 type = ffecom_type_localvar_ (s,
6948 ffesymbol_basictype (s),
6949 ffesymbol_kindtype (s));
6950 if (type == error_mark_node)
6953 t = build_decl (VAR_DECL,
6954 ffecom_get_identifier_ (ffesymbol_text (s)),
6957 TREE_STATIC (t) = TREE_STATIC (mt);
6958 DECL_INITIAL (t) = NULL_TREE;
6959 TREE_ASM_WRITTEN (t) = 1;
6963 gen_rtx (MEM, TYPE_MODE (type),
6964 plus_constant (XEXP (DECL_RTL (mt), 0),
6965 ffestorag_modulo (mst)
6966 + ffestorag_offset (st)
6967 - ffestorag_offset (mst))));
6969 t = start_decl (t, FALSE);
6971 finish_decl (t, NULL_TREE, FALSE);
6974 /* Prepare source expression for assignment into a destination perhaps known
6975 to be of a specific size. */
6978 ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
6980 ffecomConcatList_ catlist;
6985 tree tempvar = NULL_TREE;
6987 while (ffebld_op (source) == FFEBLD_opCONVERT)
6988 source = ffebld_left (source);
6990 catlist = ffecom_concat_list_new_ (source, dest_size);
6991 count = ffecom_concat_list_count_ (catlist);
6996 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
6997 FFETARGET_charactersizeNONE, count);
6999 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
7000 FFETARGET_charactersizeNONE, count);
7002 tempvar = make_tree_vec (2);
7003 TREE_VEC_ELT (tempvar, 0) = ltmp;
7004 TREE_VEC_ELT (tempvar, 1) = itmp;
7007 for (i = 0; i < count; ++i)
7008 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
7010 ffecom_concat_list_kill_ (catlist);
7014 ffebld_nonter_set_hook (source, tempvar);
7015 current_binding_level->prep_state = 1;
7019 /* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
7021 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
7022 (which generates their trees) and then their trees get push_parm_decl'd.
7024 The second arg is TRUE if the dummies are for a statement function, in
7025 which case lengths are not pushed for character arguments (since they are
7026 always known by both the caller and the callee, though the code allows
7027 for someday permitting CHAR*(*) stmtfunc dummies). */
7030 ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
7037 ffecom_transform_only_dummies_ = TRUE;
7039 /* First push the parms corresponding to actual dummy "contents". */
7041 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7043 dummy = ffebld_head (dumlist);
7044 switch (ffebld_op (dummy))
7048 continue; /* Forget alternate returns. */
7053 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7054 s = ffebld_symter (dummy);
7055 parm = ffesymbol_hook (s).decl_tree;
7056 if (parm == NULL_TREE)
7058 s = ffecom_sym_transform_ (s);
7059 parm = ffesymbol_hook (s).decl_tree;
7060 assert (parm != NULL_TREE);
7062 if (parm != error_mark_node)
7063 push_parm_decl (parm);
7066 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
7068 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7070 dummy = ffebld_head (dumlist);
7071 switch (ffebld_op (dummy))
7075 continue; /* Forget alternate returns, they mean
7081 s = ffebld_symter (dummy);
7082 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7083 continue; /* Only looking for CHARACTER arguments. */
7084 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7085 continue; /* Stmtfunc arg with known size needs no
7087 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7088 continue; /* Only looking for variables and arrays. */
7089 parm = ffesymbol_hook (s).length_tree;
7090 assert (parm != NULL_TREE);
7091 if (parm != error_mark_node)
7092 push_parm_decl (parm);
7095 ffecom_transform_only_dummies_ = FALSE;
7098 /* ffecom_start_progunit_ -- Beginning of program unit
7100 Does GNU back end stuff necessary to teach it about the start of its
7101 equivalent of a Fortran program unit. */
7104 ffecom_start_progunit_ ()
7106 ffesymbol fn = ffecom_primary_entry_;
7108 tree id; /* Identifier (name) of function. */
7109 tree type; /* Type of function. */
7110 tree result; /* Result of function. */
7111 ffeinfoBasictype bt;
7115 ffeglobalType egt = FFEGLOBAL_type;
7118 bool altentries = (ffecom_num_entrypoints_ != 0);
7121 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7122 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7123 bool main_program = FALSE;
7124 int old_lineno = lineno;
7125 const char *old_input_filename = input_filename;
7127 assert (fn != NULL);
7128 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
7130 input_filename = ffesymbol_where_filename (fn);
7131 lineno = ffesymbol_where_filelinenum (fn);
7133 switch (ffecom_primary_entry_kind_)
7135 case FFEINFO_kindPROGRAM:
7136 main_program = TRUE;
7137 gt = FFEGLOBAL_typeMAIN;
7138 bt = FFEINFO_basictypeNONE;
7139 kt = FFEINFO_kindtypeNONE;
7140 type = ffecom_tree_fun_type_void;
7145 case FFEINFO_kindBLOCKDATA:
7146 gt = FFEGLOBAL_typeBDATA;
7147 bt = FFEINFO_basictypeNONE;
7148 kt = FFEINFO_kindtypeNONE;
7149 type = ffecom_tree_fun_type_void;
7154 case FFEINFO_kindFUNCTION:
7155 gt = FFEGLOBAL_typeFUNC;
7156 egt = FFEGLOBAL_typeEXT;
7157 bt = ffesymbol_basictype (fn);
7158 kt = ffesymbol_kindtype (fn);
7159 if (bt == FFEINFO_basictypeNONE)
7161 ffeimplic_establish_symbol (fn);
7162 if (ffesymbol_funcresult (fn) != NULL)
7163 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7164 bt = ffesymbol_basictype (fn);
7165 kt = ffesymbol_kindtype (fn);
7169 charfunc = cmplxfunc = FALSE;
7170 else if (bt == FFEINFO_basictypeCHARACTER)
7171 charfunc = TRUE, cmplxfunc = FALSE;
7172 else if ((bt == FFEINFO_basictypeCOMPLEX)
7173 && ffesymbol_is_f2c (fn)
7175 charfunc = FALSE, cmplxfunc = TRUE;
7177 charfunc = cmplxfunc = FALSE;
7179 if (multi || charfunc)
7180 type = ffecom_tree_fun_type_void;
7181 else if (ffesymbol_is_f2c (fn) && !altentries)
7182 type = ffecom_tree_fun_type[bt][kt];
7184 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7186 if ((type == NULL_TREE)
7187 || (TREE_TYPE (type) == NULL_TREE))
7188 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7191 case FFEINFO_kindSUBROUTINE:
7192 gt = FFEGLOBAL_typeSUBR;
7193 egt = FFEGLOBAL_typeEXT;
7194 bt = FFEINFO_basictypeNONE;
7195 kt = FFEINFO_kindtypeNONE;
7196 if (ffecom_is_altreturning_)
7197 type = ffecom_tree_subr_type;
7199 type = ffecom_tree_fun_type_void;
7205 assert ("say what??" == NULL);
7207 case FFEINFO_kindANY:
7208 gt = FFEGLOBAL_typeANY;
7209 bt = FFEINFO_basictypeNONE;
7210 kt = FFEINFO_kindtypeNONE;
7211 type = error_mark_node;
7219 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
7220 ffesymbol_text (fn));
7222 #if FFETARGET_isENFORCED_MAIN
7223 else if (main_program)
7224 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7227 id = ffecom_get_external_identifier_ (fn);
7231 0, /* nested/inline */
7232 !altentries); /* TREE_PUBLIC */
7234 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
7237 && ((g = ffesymbol_global (fn)) != NULL)
7238 && ((ffeglobal_type (g) == gt)
7239 || (ffeglobal_type (g) == egt)))
7241 ffeglobal_set_hook (g, current_function_decl);
7244 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7245 exec-transitioning needs current_function_decl to be filled in. So we
7246 do these things in two phases. */
7249 { /* 1st arg identifies which entrypoint. */
7250 ffecom_which_entrypoint_decl_
7251 = build_decl (PARM_DECL,
7252 ffecom_get_invented_identifier ("__g77_%s",
7253 "which_entrypoint"),
7255 push_parm_decl (ffecom_which_entrypoint_decl_);
7261 { /* Arg for result (return value). */
7266 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7268 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7270 type = ffecom_multi_type_node_;
7272 result = ffecom_get_invented_identifier ("__g77_%s", "result");
7274 /* Make length arg _and_ enhance type info for CHAR arg itself. */
7277 length = ffecom_char_enhance_arg_ (&type, fn);
7279 length = NULL_TREE; /* Not ref'd if !charfunc. */
7281 type = build_pointer_type (type);
7282 result = build_decl (PARM_DECL, result, type);
7284 push_parm_decl (result);
7286 ffecom_multi_retval_ = result;
7288 ffecom_func_result_ = result;
7292 push_parm_decl (length);
7293 ffecom_func_length_ = length;
7297 if (ffecom_primary_entry_is_proc_)
7300 arglist = ffecom_master_arglist_;
7302 arglist = ffesymbol_dummyargs (fn);
7303 ffecom_push_dummy_decls_ (arglist, FALSE);
7306 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7307 store_parm_decls (main_program ? 1 : 0);
7309 ffecom_start_compstmt ();
7310 /* Disallow temp vars at this level. */
7311 current_binding_level->prep_state = 2;
7313 lineno = old_lineno;
7314 input_filename = old_input_filename;
7316 /* This handles any symbols still untransformed, in case -g specified.
7317 This used to be done in ffecom_finish_progunit, but it turns out to
7318 be necessary to do it here so that statement functions are
7319 expanded before code. But don't bother for BLOCK DATA. */
7321 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7322 ffesymbol_drive (ffecom_finish_symbol_transform_);
7325 /* ffecom_sym_transform_ -- Transform FFE sym into backend sym
7328 ffecom_sym_transform_(s);
7330 The ffesymbol_hook info for s is updated with appropriate backend info
7334 ffecom_sym_transform_ (ffesymbol s)
7336 tree t; /* Transformed thingy. */
7337 tree tlen; /* Length if CHAR*(*). */
7338 bool addr; /* Is t the address of the thingy? */
7339 ffeinfoBasictype bt;
7342 int old_lineno = lineno;
7343 const char *old_input_filename = input_filename;
7345 /* Must ensure special ASSIGN variables are declared at top of outermost
7346 block, else they'll end up in the innermost block when their first
7347 ASSIGN is seen, which leaves them out of scope when they're the
7348 subject of a GOTO or I/O statement.
7350 We make this variable even if -fugly-assign. Just let it go unused,
7351 in case it turns out there are cases where we really want to use this
7352 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
7354 if (! ffecom_transform_only_dummies_
7355 && ffesymbol_assigned (s)
7356 && ! ffesymbol_hook (s).assign_tree)
7357 s = ffecom_sym_transform_assign_ (s);
7359 if (ffesymbol_sfdummyparent (s) == NULL)
7361 input_filename = ffesymbol_where_filename (s);
7362 lineno = ffesymbol_where_filelinenum (s);
7366 ffesymbol sf = ffesymbol_sfdummyparent (s);
7368 input_filename = ffesymbol_where_filename (sf);
7369 lineno = ffesymbol_where_filelinenum (sf);
7372 bt = ffeinfo_basictype (ffebld_info (s));
7373 kt = ffeinfo_kindtype (ffebld_info (s));
7379 switch (ffesymbol_kind (s))
7381 case FFEINFO_kindNONE:
7382 switch (ffesymbol_where (s))
7384 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7385 assert (ffecom_transform_only_dummies_);
7387 /* Before 0.4, this could be ENTITY/DUMMY, but see
7388 ffestu_sym_end_transition -- no longer true (in particular, if
7389 it could be an ENTITY, it _will_ be made one, so that
7390 possibility won't come through here). So we never make length
7391 arg for CHARACTER type. */
7393 t = build_decl (PARM_DECL,
7394 ffecom_get_identifier_ (ffesymbol_text (s)),
7395 ffecom_tree_ptr_to_subr_type);
7396 DECL_ARTIFICIAL (t) = 1;
7400 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7401 assert (!ffecom_transform_only_dummies_);
7403 if (((g = ffesymbol_global (s)) != NULL)
7404 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7405 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7406 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7407 && (ffeglobal_hook (g) != NULL_TREE)
7408 && ffe_is_globals ())
7410 t = ffeglobal_hook (g);
7414 t = build_decl (FUNCTION_DECL,
7415 ffecom_get_external_identifier_ (s),
7416 ffecom_tree_subr_type); /* Assume subr. */
7417 DECL_EXTERNAL (t) = 1;
7418 TREE_PUBLIC (t) = 1;
7420 t = start_decl (t, FALSE);
7421 finish_decl (t, NULL_TREE, FALSE);
7424 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7425 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7426 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7427 ffeglobal_set_hook (g, t);
7429 ffecom_save_tree_forever (t);
7434 assert ("NONE where unexpected" == NULL);
7436 case FFEINFO_whereANY:
7441 case FFEINFO_kindENTITY:
7442 switch (ffeinfo_where (ffesymbol_info (s)))
7445 case FFEINFO_whereCONSTANT:
7446 /* ~~Debugging info needed? */
7447 assert (!ffecom_transform_only_dummies_);
7448 t = error_mark_node; /* Shouldn't ever see this in expr. */
7451 case FFEINFO_whereLOCAL:
7452 assert (!ffecom_transform_only_dummies_);
7455 ffestorag st = ffesymbol_storage (s);
7459 && (ffestorag_size (st) == 0))
7461 t = error_mark_node;
7465 type = ffecom_type_localvar_ (s, bt, kt);
7467 if (type == error_mark_node)
7469 t = error_mark_node;
7474 && (ffestorag_parent (st) != NULL))
7475 { /* Child of EQUIVALENCE parent. */
7478 ffetargetOffset offset;
7480 est = ffestorag_parent (st);
7481 ffecom_transform_equiv_ (est);
7483 et = ffestorag_hook (est);
7484 assert (et != NULL_TREE);
7486 if (! TREE_STATIC (et))
7487 put_var_into_stack (et);
7489 offset = ffestorag_modulo (est)
7490 + ffestorag_offset (ffesymbol_storage (s))
7491 - ffestorag_offset (est);
7493 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
7495 /* (t_type *) (((char *) &et) + offset) */
7497 t = convert (string_type_node, /* (char *) */
7498 ffecom_1 (ADDR_EXPR,
7499 build_pointer_type (TREE_TYPE (et)),
7501 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7503 build_int_2 (offset, 0));
7504 t = convert (build_pointer_type (type),
7506 TREE_CONSTANT (t) = staticp (et);
7513 bool init = ffesymbol_is_init (s);
7515 t = build_decl (VAR_DECL,
7516 ffecom_get_identifier_ (ffesymbol_text (s)),
7520 || ffesymbol_namelisted (s)
7521 #ifdef FFECOM_sizeMAXSTACKITEM
7523 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7525 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7526 && (ffecom_primary_entry_kind_
7527 != FFEINFO_kindBLOCKDATA)
7528 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7529 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7531 TREE_STATIC (t) = 0; /* No need to make static. */
7533 if (init || ffe_is_init_local_zero ())
7534 DECL_INITIAL (t) = error_mark_node;
7536 /* Keep -Wunused from complaining about var if it
7537 is used as sfunc arg or DATA implied-DO. */
7538 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7539 DECL_IN_SYSTEM_HEADER (t) = 1;
7541 t = start_decl (t, FALSE);
7545 if (ffesymbol_init (s) != NULL)
7546 initexpr = ffecom_expr (ffesymbol_init (s));
7548 initexpr = ffecom_init_zero_ (t);
7550 else if (ffe_is_init_local_zero ())
7551 initexpr = ffecom_init_zero_ (t);
7553 initexpr = NULL_TREE; /* Not ref'd if !init. */
7555 finish_decl (t, initexpr, FALSE);
7557 if (st != NULL && DECL_SIZE (t) != error_mark_node)
7559 assert (TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST);
7560 assert (0 == compare_tree_int (DECL_SIZE_UNIT (t),
7561 ffestorag_size (st)));
7567 case FFEINFO_whereRESULT:
7568 assert (!ffecom_transform_only_dummies_);
7570 if (bt == FFEINFO_basictypeCHARACTER)
7571 { /* Result is already in list of dummies, use
7573 t = ffecom_func_result_;
7574 tlen = ffecom_func_length_;
7578 if ((ffecom_num_entrypoints_ == 0)
7579 && (bt == FFEINFO_basictypeCOMPLEX)
7580 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7581 { /* Result is already in list of dummies, use
7583 t = ffecom_func_result_;
7587 if (ffecom_func_result_ != NULL_TREE)
7589 t = ffecom_func_result_;
7592 if ((ffecom_num_entrypoints_ != 0)
7593 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7595 assert (ffecom_multi_retval_ != NULL_TREE);
7596 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7597 ffecom_multi_retval_);
7598 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7599 t, ffecom_multi_fields_[bt][kt]);
7604 t = build_decl (VAR_DECL,
7605 ffecom_get_identifier_ (ffesymbol_text (s)),
7606 ffecom_tree_type[bt][kt]);
7607 TREE_STATIC (t) = 0; /* Put result on stack. */
7608 t = start_decl (t, FALSE);
7609 finish_decl (t, NULL_TREE, FALSE);
7611 ffecom_func_result_ = t;
7615 case FFEINFO_whereDUMMY:
7623 bool adjustable = FALSE; /* Conditionally adjustable? */
7625 type = ffecom_tree_type[bt][kt];
7626 if (ffesymbol_sfdummyparent (s) != NULL)
7628 if (current_function_decl == ffecom_outer_function_decl_)
7629 { /* Exec transition before sfunc
7630 context; get it later. */
7633 t = ffecom_get_identifier_ (ffesymbol_text
7634 (ffesymbol_sfdummyparent (s)));
7637 t = ffecom_get_identifier_ (ffesymbol_text (s));
7639 assert (ffecom_transform_only_dummies_);
7641 old_sizes = get_pending_sizes ();
7642 put_pending_sizes (old_sizes);
7644 if (bt == FFEINFO_basictypeCHARACTER)
7645 tlen = ffecom_char_enhance_arg_ (&type, s);
7646 type = ffecom_check_size_overflow_ (s, type, TRUE);
7648 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7650 if (type == error_mark_node)
7653 dim = ffebld_head (dl);
7654 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7655 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7656 low = ffecom_integer_one_node;
7658 low = ffecom_expr (ffebld_left (dim));
7659 assert (ffebld_right (dim) != NULL);
7660 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7661 || ffecom_doing_entry_)
7663 /* Used to just do high=low. But for ffecom_tree_
7664 canonize_ref_, it probably is important to correctly
7665 assess the size. E.g. given COMPLEX C(*),CFUNC and
7666 C(2)=CFUNC(C), overlap can happen, while it can't
7667 for, say, C(1)=CFUNC(C(2)). */
7668 /* Even more recently used to set to INT_MAX, but that
7669 broke when some overflow checking went into the back
7670 end. Now we just leave the upper bound unspecified. */
7674 high = ffecom_expr (ffebld_right (dim));
7676 /* Determine whether array is conditionally adjustable,
7677 to decide whether back-end magic is needed.
7679 Normally the front end uses the back-end function
7680 variable_size to wrap SAVE_EXPR's around expressions
7681 affecting the size/shape of an array so that the
7682 size/shape info doesn't change during execution
7683 of the compiled code even though variables and
7684 functions referenced in those expressions might.
7686 variable_size also makes sure those saved expressions
7687 get evaluated immediately upon entry to the
7688 compiled procedure -- the front end normally doesn't
7689 have to worry about that.
7691 However, there is a problem with this that affects
7692 g77's implementation of entry points, and that is
7693 that it is _not_ true that each invocation of the
7694 compiled procedure is permitted to evaluate
7695 array size/shape info -- because it is possible
7696 that, for some invocations, that info is invalid (in
7697 which case it is "promised" -- i.e. a violation of
7698 the Fortran standard -- that the compiled code
7699 won't reference the array or its size/shape
7700 during that particular invocation).
7702 To phrase this in C terms, consider this gcc function:
7704 void foo (int *n, float (*a)[*n])
7706 // a is "pointer to array ...", fyi.
7709 Suppose that, for some invocations, it is permitted
7710 for a caller of foo to do this:
7714 Now the _written_ code for foo can take such a call
7715 into account by either testing explicitly for whether
7716 (a == NULL) || (n == NULL) -- presumably it is
7717 not permitted to reference *a in various fashions
7718 if (n == NULL) I suppose -- or it can avoid it by
7719 looking at other info (other arguments, static/global
7722 However, this won't work in gcc 2.5.8 because it'll
7723 automatically emit the code to save the "*n"
7724 expression, which'll yield a NULL dereference for
7725 the "foo (NULL, NULL)" call, something the code
7726 for foo cannot prevent.
7728 g77 definitely needs to avoid executing such
7729 code anytime the pointer to the adjustable array
7730 is NULL, because even if its bounds expressions
7731 don't have any references to possible "absent"
7732 variables like "*n" -- say all variable references
7733 are to COMMON variables, i.e. global (though in C,
7734 local static could actually make sense) -- the
7735 expressions could yield other run-time problems
7736 for allowably "dead" values in those variables.
7738 For example, let's consider a more complicated
7744 void foo (float (*a)[i/j])
7749 The above is (essentially) quite valid for Fortran
7750 but, again, for a call like "foo (NULL);", it is
7751 permitted for i and j to be undefined when the
7752 call is made. If j happened to be zero, for
7753 example, emitting the code to evaluate "i/j"
7754 could result in a run-time error.
7756 Offhand, though I don't have my F77 or F90
7757 standards handy, it might even be valid for a
7758 bounds expression to contain a function reference,
7759 in which case I doubt it is permitted for an
7760 implementation to invoke that function in the
7761 Fortran case involved here (invocation of an
7762 alternate ENTRY point that doesn't have the adjustable
7763 array as one of its arguments).
7765 So, the code that the compiler would normally emit
7766 to preevaluate the size/shape info for an
7767 adjustable array _must not_ be executed at run time
7768 in certain cases. Specifically, for Fortran,
7769 the case is when the pointer to the adjustable
7770 array == NULL. (For gnu-ish C, it might be nice
7771 for the source code itself to specify an expression
7772 that, if TRUE, inhibits execution of the code. Or
7773 reverse the sense for elegance.)
7775 (Note that g77 could use a different test than NULL,
7776 actually, since it happens to always pass an
7777 integer to the called function that specifies which
7778 entry point is being invoked. Hmm, this might
7779 solve the next problem.)
7781 One way a user could, I suppose, write "foo" so
7782 it works is to insert COND_EXPR's for the
7783 size/shape info so the dangerous stuff isn't
7784 actually done, as in:
7786 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7791 The next problem is that the front end needs to
7792 be able to tell the back end about the array's
7793 decl _before_ it tells it about the conditional
7794 expression to inhibit evaluation of size/shape info,
7797 To solve this, the front end needs to be able
7798 to give the back end the expression to inhibit
7799 generation of the preevaluation code _after_
7800 it makes the decl for the adjustable array.
7802 Until then, the above example using the COND_EXPR
7803 doesn't pass muster with gcc because the "(a == NULL)"
7804 part has a reference to "a", which is still
7805 undefined at that point.
7807 g77 will therefore use a different mechanism in the
7811 && ((TREE_CODE (low) != INTEGER_CST)
7812 || (high && TREE_CODE (high) != INTEGER_CST)))
7815 #if 0 /* Old approach -- see below. */
7816 if (TREE_CODE (low) != INTEGER_CST)
7817 low = ffecom_3 (COND_EXPR, integer_type_node,
7818 ffecom_adjarray_passed_ (s),
7820 ffecom_integer_zero_node);
7822 if (high && TREE_CODE (high) != INTEGER_CST)
7823 high = ffecom_3 (COND_EXPR, integer_type_node,
7824 ffecom_adjarray_passed_ (s),
7826 ffecom_integer_zero_node);
7829 /* ~~~gcc/stor-layout.c (layout_type) should do this,
7830 probably. Fixes 950302-1.f. */
7832 if (TREE_CODE (low) != INTEGER_CST)
7833 low = variable_size (low);
7835 /* ~~~Similarly, this fixes dumb0.f. The C front end
7836 does this, which is why dumb0.c would work. */
7838 if (high && TREE_CODE (high) != INTEGER_CST)
7839 high = variable_size (high);
7844 build_range_type (ffecom_integer_type_node,
7846 type = ffecom_check_size_overflow_ (s, type, TRUE);
7849 if (type == error_mark_node)
7851 t = error_mark_node;
7855 if ((ffesymbol_sfdummyparent (s) == NULL)
7856 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
7858 type = build_pointer_type (type);
7862 t = build_decl (PARM_DECL, t, type);
7863 DECL_ARTIFICIAL (t) = 1;
7865 /* If this arg is present in every entry point's list of
7866 dummy args, then we're done. */
7868 if (ffesymbol_numentries (s)
7869 == (ffecom_num_entrypoints_ + 1))
7874 /* If variable_size in stor-layout has been called during
7875 the above, then get_pending_sizes should have the
7876 yet-to-be-evaluated saved expressions pending.
7877 Make the whole lot of them get emitted, conditionally
7878 on whether the array decl ("t" above) is not NULL. */
7881 tree sizes = get_pending_sizes ();
7886 tem = TREE_CHAIN (tem))
7888 tree temv = TREE_VALUE (tem);
7894 = ffecom_2 (COMPOUND_EXPR,
7903 = ffecom_3 (COND_EXPR,
7910 convert (TREE_TYPE (sizes),
7911 integer_zero_node));
7912 sizes = ffecom_save_tree (sizes);
7915 = tree_cons (NULL_TREE, sizes, tem);
7919 put_pending_sizes (sizes);
7925 && (ffesymbol_numentries (s)
7926 != ffecom_num_entrypoints_ + 1))
7928 = ffecom_2 (NE_EXPR, integer_type_node,
7934 && (ffesymbol_numentries (s)
7935 != ffecom_num_entrypoints_ + 1))
7937 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
7938 ffebad_here (0, ffesymbol_where_line (s),
7939 ffesymbol_where_column (s));
7940 ffebad_string (ffesymbol_text (s));
7949 case FFEINFO_whereCOMMON:
7954 ffestorag st = ffesymbol_storage (s);
7957 cs = ffesymbol_common (s); /* The COMMON area itself. */
7958 if (st != NULL) /* Else not laid out. */
7960 ffecom_transform_common_ (cs);
7961 st = ffesymbol_storage (s);
7964 type = ffecom_type_localvar_ (s, bt, kt);
7966 cg = ffesymbol_global (cs); /* The global COMMON info. */
7968 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
7971 ct = ffeglobal_hook (cg); /* The common area's tree. */
7973 if ((ct == NULL_TREE)
7975 || (type == error_mark_node))
7976 t = error_mark_node;
7979 ffetargetOffset offset;
7982 cst = ffestorag_parent (st);
7983 assert (cst == ffesymbol_storage (cs));
7985 offset = ffestorag_modulo (cst)
7986 + ffestorag_offset (st)
7987 - ffestorag_offset (cst);
7989 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
7991 /* (t_type *) (((char *) &ct) + offset) */
7993 t = convert (string_type_node, /* (char *) */
7994 ffecom_1 (ADDR_EXPR,
7995 build_pointer_type (TREE_TYPE (ct)),
7997 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7999 build_int_2 (offset, 0));
8000 t = convert (build_pointer_type (type),
8002 TREE_CONSTANT (t) = 1;
8009 case FFEINFO_whereIMMEDIATE:
8010 case FFEINFO_whereGLOBAL:
8011 case FFEINFO_whereFLEETING:
8012 case FFEINFO_whereFLEETING_CADDR:
8013 case FFEINFO_whereFLEETING_IADDR:
8014 case FFEINFO_whereINTRINSIC:
8015 case FFEINFO_whereCONSTANT_SUBOBJECT:
8017 assert ("ENTITY where unheard of" == NULL);
8019 case FFEINFO_whereANY:
8020 t = error_mark_node;
8025 case FFEINFO_kindFUNCTION:
8026 switch (ffeinfo_where (ffesymbol_info (s)))
8028 case FFEINFO_whereLOCAL: /* Me. */
8029 assert (!ffecom_transform_only_dummies_);
8030 t = current_function_decl;
8033 case FFEINFO_whereGLOBAL:
8034 assert (!ffecom_transform_only_dummies_);
8036 if (((g = ffesymbol_global (s)) != NULL)
8037 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8038 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8039 && (ffeglobal_hook (g) != NULL_TREE)
8040 && ffe_is_globals ())
8042 t = ffeglobal_hook (g);
8046 if (ffesymbol_is_f2c (s)
8047 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8048 t = ffecom_tree_fun_type[bt][kt];
8050 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
8052 t = build_decl (FUNCTION_DECL,
8053 ffecom_get_external_identifier_ (s),
8055 DECL_EXTERNAL (t) = 1;
8056 TREE_PUBLIC (t) = 1;
8058 t = start_decl (t, FALSE);
8059 finish_decl (t, NULL_TREE, FALSE);
8062 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8063 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8064 ffeglobal_set_hook (g, t);
8066 ffecom_save_tree_forever (t);
8070 case FFEINFO_whereDUMMY:
8071 assert (ffecom_transform_only_dummies_);
8073 if (ffesymbol_is_f2c (s)
8074 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8075 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8077 t = build_pointer_type
8078 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8080 t = build_decl (PARM_DECL,
8081 ffecom_get_identifier_ (ffesymbol_text (s)),
8083 DECL_ARTIFICIAL (t) = 1;
8087 case FFEINFO_whereCONSTANT: /* Statement function. */
8088 assert (!ffecom_transform_only_dummies_);
8089 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8092 case FFEINFO_whereINTRINSIC:
8093 assert (!ffecom_transform_only_dummies_);
8094 break; /* Let actual references generate their
8098 assert ("FUNCTION where unheard of" == NULL);
8100 case FFEINFO_whereANY:
8101 t = error_mark_node;
8106 case FFEINFO_kindSUBROUTINE:
8107 switch (ffeinfo_where (ffesymbol_info (s)))
8109 case FFEINFO_whereLOCAL: /* Me. */
8110 assert (!ffecom_transform_only_dummies_);
8111 t = current_function_decl;
8114 case FFEINFO_whereGLOBAL:
8115 assert (!ffecom_transform_only_dummies_);
8117 if (((g = ffesymbol_global (s)) != NULL)
8118 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8119 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8120 && (ffeglobal_hook (g) != NULL_TREE)
8121 && ffe_is_globals ())
8123 t = ffeglobal_hook (g);
8127 t = build_decl (FUNCTION_DECL,
8128 ffecom_get_external_identifier_ (s),
8129 ffecom_tree_subr_type);
8130 DECL_EXTERNAL (t) = 1;
8131 TREE_PUBLIC (t) = 1;
8133 t = start_decl (t, FALSE);
8134 finish_decl (t, NULL_TREE, FALSE);
8137 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8138 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8139 ffeglobal_set_hook (g, t);
8141 ffecom_save_tree_forever (t);
8145 case FFEINFO_whereDUMMY:
8146 assert (ffecom_transform_only_dummies_);
8148 t = build_decl (PARM_DECL,
8149 ffecom_get_identifier_ (ffesymbol_text (s)),
8150 ffecom_tree_ptr_to_subr_type);
8151 DECL_ARTIFICIAL (t) = 1;
8155 case FFEINFO_whereINTRINSIC:
8156 assert (!ffecom_transform_only_dummies_);
8157 break; /* Let actual references generate their
8161 assert ("SUBROUTINE where unheard of" == NULL);
8163 case FFEINFO_whereANY:
8164 t = error_mark_node;
8169 case FFEINFO_kindPROGRAM:
8170 switch (ffeinfo_where (ffesymbol_info (s)))
8172 case FFEINFO_whereLOCAL: /* Me. */
8173 assert (!ffecom_transform_only_dummies_);
8174 t = current_function_decl;
8177 case FFEINFO_whereCOMMON:
8178 case FFEINFO_whereDUMMY:
8179 case FFEINFO_whereGLOBAL:
8180 case FFEINFO_whereRESULT:
8181 case FFEINFO_whereFLEETING:
8182 case FFEINFO_whereFLEETING_CADDR:
8183 case FFEINFO_whereFLEETING_IADDR:
8184 case FFEINFO_whereIMMEDIATE:
8185 case FFEINFO_whereINTRINSIC:
8186 case FFEINFO_whereCONSTANT:
8187 case FFEINFO_whereCONSTANT_SUBOBJECT:
8189 assert ("PROGRAM where unheard of" == NULL);
8191 case FFEINFO_whereANY:
8192 t = error_mark_node;
8197 case FFEINFO_kindBLOCKDATA:
8198 switch (ffeinfo_where (ffesymbol_info (s)))
8200 case FFEINFO_whereLOCAL: /* Me. */
8201 assert (!ffecom_transform_only_dummies_);
8202 t = current_function_decl;
8205 case FFEINFO_whereGLOBAL:
8206 assert (!ffecom_transform_only_dummies_);
8208 t = build_decl (FUNCTION_DECL,
8209 ffecom_get_external_identifier_ (s),
8210 ffecom_tree_blockdata_type);
8211 DECL_EXTERNAL (t) = 1;
8212 TREE_PUBLIC (t) = 1;
8214 t = start_decl (t, FALSE);
8215 finish_decl (t, NULL_TREE, FALSE);
8217 ffecom_save_tree_forever (t);
8221 case FFEINFO_whereCOMMON:
8222 case FFEINFO_whereDUMMY:
8223 case FFEINFO_whereRESULT:
8224 case FFEINFO_whereFLEETING:
8225 case FFEINFO_whereFLEETING_CADDR:
8226 case FFEINFO_whereFLEETING_IADDR:
8227 case FFEINFO_whereIMMEDIATE:
8228 case FFEINFO_whereINTRINSIC:
8229 case FFEINFO_whereCONSTANT:
8230 case FFEINFO_whereCONSTANT_SUBOBJECT:
8232 assert ("BLOCKDATA where unheard of" == NULL);
8234 case FFEINFO_whereANY:
8235 t = error_mark_node;
8240 case FFEINFO_kindCOMMON:
8241 switch (ffeinfo_where (ffesymbol_info (s)))
8243 case FFEINFO_whereLOCAL:
8244 assert (!ffecom_transform_only_dummies_);
8245 ffecom_transform_common_ (s);
8248 case FFEINFO_whereNONE:
8249 case FFEINFO_whereCOMMON:
8250 case FFEINFO_whereDUMMY:
8251 case FFEINFO_whereGLOBAL:
8252 case FFEINFO_whereRESULT:
8253 case FFEINFO_whereFLEETING:
8254 case FFEINFO_whereFLEETING_CADDR:
8255 case FFEINFO_whereFLEETING_IADDR:
8256 case FFEINFO_whereIMMEDIATE:
8257 case FFEINFO_whereINTRINSIC:
8258 case FFEINFO_whereCONSTANT:
8259 case FFEINFO_whereCONSTANT_SUBOBJECT:
8261 assert ("COMMON where unheard of" == NULL);
8263 case FFEINFO_whereANY:
8264 t = error_mark_node;
8269 case FFEINFO_kindCONSTRUCT:
8270 switch (ffeinfo_where (ffesymbol_info (s)))
8272 case FFEINFO_whereLOCAL:
8273 assert (!ffecom_transform_only_dummies_);
8276 case FFEINFO_whereNONE:
8277 case FFEINFO_whereCOMMON:
8278 case FFEINFO_whereDUMMY:
8279 case FFEINFO_whereGLOBAL:
8280 case FFEINFO_whereRESULT:
8281 case FFEINFO_whereFLEETING:
8282 case FFEINFO_whereFLEETING_CADDR:
8283 case FFEINFO_whereFLEETING_IADDR:
8284 case FFEINFO_whereIMMEDIATE:
8285 case FFEINFO_whereINTRINSIC:
8286 case FFEINFO_whereCONSTANT:
8287 case FFEINFO_whereCONSTANT_SUBOBJECT:
8289 assert ("CONSTRUCT where unheard of" == NULL);
8291 case FFEINFO_whereANY:
8292 t = error_mark_node;
8297 case FFEINFO_kindNAMELIST:
8298 switch (ffeinfo_where (ffesymbol_info (s)))
8300 case FFEINFO_whereLOCAL:
8301 assert (!ffecom_transform_only_dummies_);
8302 t = ffecom_transform_namelist_ (s);
8305 case FFEINFO_whereNONE:
8306 case FFEINFO_whereCOMMON:
8307 case FFEINFO_whereDUMMY:
8308 case FFEINFO_whereGLOBAL:
8309 case FFEINFO_whereRESULT:
8310 case FFEINFO_whereFLEETING:
8311 case FFEINFO_whereFLEETING_CADDR:
8312 case FFEINFO_whereFLEETING_IADDR:
8313 case FFEINFO_whereIMMEDIATE:
8314 case FFEINFO_whereINTRINSIC:
8315 case FFEINFO_whereCONSTANT:
8316 case FFEINFO_whereCONSTANT_SUBOBJECT:
8318 assert ("NAMELIST where unheard of" == NULL);
8320 case FFEINFO_whereANY:
8321 t = error_mark_node;
8327 assert ("kind unheard of" == NULL);
8329 case FFEINFO_kindANY:
8330 t = error_mark_node;
8334 ffesymbol_hook (s).decl_tree = t;
8335 ffesymbol_hook (s).length_tree = tlen;
8336 ffesymbol_hook (s).addr = addr;
8338 lineno = old_lineno;
8339 input_filename = old_input_filename;
8344 /* Transform into ASSIGNable symbol.
8346 Symbol has already been transformed, but for whatever reason, the
8347 resulting decl_tree has been deemed not usable for an ASSIGN target.
8348 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8349 another local symbol of type void * and stuff that in the assign_tree
8350 argument. The F77/F90 standards allow this implementation. */
8353 ffecom_sym_transform_assign_ (ffesymbol s)
8355 tree t; /* Transformed thingy. */
8356 int old_lineno = lineno;
8357 const char *old_input_filename = input_filename;
8359 if (ffesymbol_sfdummyparent (s) == NULL)
8361 input_filename = ffesymbol_where_filename (s);
8362 lineno = ffesymbol_where_filelinenum (s);
8366 ffesymbol sf = ffesymbol_sfdummyparent (s);
8368 input_filename = ffesymbol_where_filename (sf);
8369 lineno = ffesymbol_where_filelinenum (sf);
8372 assert (!ffecom_transform_only_dummies_);
8374 t = build_decl (VAR_DECL,
8375 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
8376 ffesymbol_text (s)),
8377 TREE_TYPE (null_pointer_node));
8379 switch (ffesymbol_where (s))
8381 case FFEINFO_whereLOCAL:
8382 /* Unlike for regular vars, SAVE status is easy to determine for
8383 ASSIGNed vars, since there's no initialization, there's no
8384 effective storage association (so "SAVE J" does not apply to
8385 K even given "EQUIVALENCE (J,K)"), there's no size issue
8386 to worry about, etc. */
8387 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8388 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8389 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8390 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8392 TREE_STATIC (t) = 0; /* No need to make static. */
8395 case FFEINFO_whereCOMMON:
8396 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8399 case FFEINFO_whereDUMMY:
8400 /* Note that twinning a DUMMY means the caller won't see
8401 the ASSIGNed value. But both F77 and F90 allow implementations
8402 to do this, i.e. disallow Fortran code that would try and
8403 take advantage of actually putting a label into a variable
8404 via a dummy argument (or any other storage association, for
8406 TREE_STATIC (t) = 0;
8410 TREE_STATIC (t) = 0;
8414 t = start_decl (t, FALSE);
8415 finish_decl (t, NULL_TREE, FALSE);
8417 ffesymbol_hook (s).assign_tree = t;
8419 lineno = old_lineno;
8420 input_filename = old_input_filename;
8425 /* Implement COMMON area in back end.
8427 Because COMMON-based variables can be referenced in the dimension
8428 expressions of dummy (adjustable) arrays, and because dummies
8429 (in the gcc back end) need to be put in the outer binding level
8430 of a function (which has two binding levels, the outer holding
8431 the dummies and the inner holding the other vars), special care
8432 must be taken to handle COMMON areas.
8434 The current strategy is basically to always tell the back end about
8435 the COMMON area as a top-level external reference to just a block
8436 of storage of the master type of that area (e.g. integer, real,
8437 character, whatever -- not a structure). As a distinct action,
8438 if initial values are provided, tell the back end about the area
8439 as a top-level non-external (initialized) area and remember not to
8440 allow further initialization or expansion of the area. Meanwhile,
8441 if no initialization happens at all, tell the back end about
8442 the largest size we've seen declared so the space does get reserved.
8443 (This function doesn't handle all that stuff, but it does some
8444 of the important things.)
8446 Meanwhile, for COMMON variables themselves, just keep creating
8447 references like *((float *) (&common_area + offset)) each time
8448 we reference the variable. In other words, don't make a VAR_DECL
8449 or any kind of component reference (like we used to do before 0.4),
8450 though we might do that as well just for debugging purposes (and
8451 stuff the rtl with the appropriate offset expression). */
8454 ffecom_transform_common_ (ffesymbol s)
8456 ffestorag st = ffesymbol_storage (s);
8457 ffeglobal g = ffesymbol_global (s);
8462 bool is_init = ffestorag_is_init (st);
8464 assert (st != NULL);
8467 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8470 /* First update the size of the area in global terms. */
8472 ffeglobal_size_common (s, ffestorag_size (st));
8474 if (!ffeglobal_common_init (g))
8475 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
8477 cbt = ffeglobal_hook (g);
8479 /* If we already have declared this common block for a previous program
8480 unit, and either we already initialized it or we don't have new
8481 initialization for it, just return what we have without changing it. */
8483 if ((cbt != NULL_TREE)
8485 || !DECL_EXTERNAL (cbt)))
8487 if (st->hook == NULL) ffestorag_set_hook (st, cbt);
8491 /* Process inits. */
8495 if (ffestorag_init (st) != NULL)
8499 /* Set the padding for the expression, so ffecom_expr
8500 knows to insert that many zeros. */
8501 switch (ffebld_op (sexp = ffestorag_init (st)))
8503 case FFEBLD_opCONTER:
8504 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
8507 case FFEBLD_opARRTER:
8508 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8511 case FFEBLD_opACCTER:
8512 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8516 assert ("bad op for cmn init (pad)" == NULL);
8520 init = ffecom_expr (sexp);
8521 if (init == error_mark_node)
8522 { /* Hopefully the back end complained! */
8524 if (cbt != NULL_TREE)
8529 init = error_mark_node;
8534 /* cbtype must be permanently allocated! */
8536 /* Allocate the MAX of the areas so far, seen filewide. */
8537 high = build_int_2 ((ffeglobal_common_size (g)
8538 + ffeglobal_common_pad (g)) - 1, 0);
8539 TREE_TYPE (high) = ffecom_integer_type_node;
8542 cbtype = build_array_type (char_type_node,
8543 build_range_type (integer_type_node,
8547 cbtype = build_array_type (char_type_node, NULL_TREE);
8549 if (cbt == NULL_TREE)
8552 = build_decl (VAR_DECL,
8553 ffecom_get_external_identifier_ (s),
8555 TREE_STATIC (cbt) = 1;
8556 TREE_PUBLIC (cbt) = 1;
8561 TREE_TYPE (cbt) = cbtype;
8563 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8564 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
8566 cbt = start_decl (cbt, TRUE);
8567 if (ffeglobal_hook (g) != NULL)
8568 assert (cbt == ffeglobal_hook (g));
8570 assert (!init || !DECL_EXTERNAL (cbt));
8572 /* Make sure that any type can live in COMMON and be referenced
8573 without getting a bus error. We could pick the most restrictive
8574 alignment of all entities actually placed in the COMMON, but
8575 this seems easy enough. */
8577 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
8578 DECL_USER_ALIGN (cbt) = 0;
8580 if (is_init && (ffestorag_init (st) == NULL))
8581 init = ffecom_init_zero_ (cbt);
8583 finish_decl (cbt, init, TRUE);
8586 ffestorag_set_init (st, ffebld_new_any ());
8590 assert (DECL_SIZE_UNIT (cbt) != NULL_TREE);
8591 assert (TREE_CODE (DECL_SIZE_UNIT (cbt)) == INTEGER_CST);
8592 assert (0 == compare_tree_int (DECL_SIZE_UNIT (cbt),
8593 (ffeglobal_common_size (g)
8594 + ffeglobal_common_pad (g))));
8597 ffeglobal_set_hook (g, cbt);
8599 ffestorag_set_hook (st, cbt);
8601 ffecom_save_tree_forever (cbt);
8604 /* Make master area for local EQUIVALENCE. */
8607 ffecom_transform_equiv_ (ffestorag eqst)
8613 bool is_init = ffestorag_is_init (eqst);
8615 assert (eqst != NULL);
8617 eqt = ffestorag_hook (eqst);
8619 if (eqt != NULL_TREE)
8622 /* Process inits. */
8626 if (ffestorag_init (eqst) != NULL)
8630 /* Set the padding for the expression, so ffecom_expr
8631 knows to insert that many zeros. */
8632 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8634 case FFEBLD_opCONTER:
8635 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8638 case FFEBLD_opARRTER:
8639 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8642 case FFEBLD_opACCTER:
8643 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8647 assert ("bad op for eqv init (pad)" == NULL);
8651 init = ffecom_expr (sexp);
8652 if (init == error_mark_node)
8653 init = NULL_TREE; /* Hopefully the back end complained! */
8656 init = error_mark_node;
8658 else if (ffe_is_init_local_zero ())
8659 init = error_mark_node;
8663 ffecom_member_namelisted_ = FALSE;
8664 ffestorag_drive (ffestorag_list_equivs (eqst),
8665 &ffecom_member_phase1_,
8668 high = build_int_2 ((ffestorag_size (eqst)
8669 + ffestorag_modulo (eqst)) - 1, 0);
8670 TREE_TYPE (high) = ffecom_integer_type_node;
8672 eqtype = build_array_type (char_type_node,
8673 build_range_type (ffecom_integer_type_node,
8674 ffecom_integer_zero_node,
8677 eqt = build_decl (VAR_DECL,
8678 ffecom_get_invented_identifier ("__g77_equiv_%s",
8680 (ffestorag_symbol (eqst))),
8682 DECL_EXTERNAL (eqt) = 0;
8684 || ffecom_member_namelisted_
8685 #ifdef FFECOM_sizeMAXSTACKITEM
8686 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8688 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8689 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8690 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8691 TREE_STATIC (eqt) = 1;
8693 TREE_STATIC (eqt) = 0;
8694 TREE_PUBLIC (eqt) = 0;
8695 TREE_ADDRESSABLE (eqt) = 1; /* Ensure non-register allocation */
8696 DECL_CONTEXT (eqt) = current_function_decl;
8698 DECL_INITIAL (eqt) = error_mark_node;
8700 DECL_INITIAL (eqt) = NULL_TREE;
8702 eqt = start_decl (eqt, FALSE);
8704 /* Make sure that any type can live in EQUIVALENCE and be referenced
8705 without getting a bus error. We could pick the most restrictive
8706 alignment of all entities actually placed in the EQUIVALENCE, but
8707 this seems easy enough. */
8709 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
8710 DECL_USER_ALIGN (eqt) = 0;
8712 if ((!is_init && ffe_is_init_local_zero ())
8713 || (is_init && (ffestorag_init (eqst) == NULL)))
8714 init = ffecom_init_zero_ (eqt);
8716 finish_decl (eqt, init, FALSE);
8719 ffestorag_set_init (eqst, ffebld_new_any ());
8722 assert (TREE_CODE (DECL_SIZE_UNIT (eqt)) == INTEGER_CST);
8723 assert (0 == compare_tree_int (DECL_SIZE_UNIT (eqt),
8724 (ffestorag_size (eqst)
8725 + ffestorag_modulo (eqst))));
8728 ffestorag_set_hook (eqst, eqt);
8730 ffestorag_drive (ffestorag_list_equivs (eqst),
8731 &ffecom_member_phase2_,
8735 /* Implement NAMELIST in back end. See f2c/format.c for more info. */
8738 ffecom_transform_namelist_ (ffesymbol s)
8741 tree nmltype = ffecom_type_namelist_ ();
8749 static int mynumber = 0;
8751 nmlt = build_decl (VAR_DECL,
8752 ffecom_get_invented_identifier ("__g77_namelist_%d",
8755 TREE_STATIC (nmlt) = 1;
8756 DECL_INITIAL (nmlt) = error_mark_node;
8758 nmlt = start_decl (nmlt, FALSE);
8760 /* Process inits. */
8762 i = strlen (ffesymbol_text (s));
8764 high = build_int_2 (i, 0);
8765 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
8767 nameinit = ffecom_build_f2c_string_ (i + 1,
8768 ffesymbol_text (s));
8769 TREE_TYPE (nameinit)
8770 = build_type_variant
8773 build_range_type (ffecom_f2c_ftnlen_type_node,
8774 ffecom_f2c_ftnlen_one_node,
8777 TREE_CONSTANT (nameinit) = 1;
8778 TREE_STATIC (nameinit) = 1;
8779 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
8782 varsinit = ffecom_vardesc_array_ (s);
8783 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
8785 TREE_CONSTANT (varsinit) = 1;
8786 TREE_STATIC (varsinit) = 1;
8791 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
8794 nvarsinit = build_int_2 (i, 0);
8795 TREE_TYPE (nvarsinit) = integer_type_node;
8796 TREE_CONSTANT (nvarsinit) = 1;
8797 TREE_STATIC (nvarsinit) = 1;
8799 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
8800 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
8802 TREE_CHAIN (TREE_CHAIN (nmlinits))
8803 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
8805 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
8806 TREE_CONSTANT (nmlinits) = 1;
8807 TREE_STATIC (nmlinits) = 1;
8809 finish_decl (nmlt, nmlinits, FALSE);
8811 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
8816 /* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
8817 analyzed on the assumption it is calculating a pointer to be
8818 indirected through. It must return the proper decl and offset,
8819 taking into account different units of measurements for offsets. */
8822 ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
8825 switch (TREE_CODE (t))
8829 case NON_LVALUE_EXPR:
8830 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
8834 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
8835 if ((*decl == NULL_TREE)
8836 || (*decl == error_mark_node))
8839 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
8841 /* An offset into COMMON. */
8842 *offset = fold (build (PLUS_EXPR, TREE_TYPE (*offset),
8843 *offset, TREE_OPERAND (t, 1)));
8844 /* Convert offset (presumably in bytes) into canonical units
8845 (presumably bits). */
8846 *offset = size_binop (MULT_EXPR,
8847 convert (bitsizetype, *offset),
8848 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))));
8851 /* Not a COMMON reference, so an unrecognized pattern. */
8852 *decl = error_mark_node;
8857 *offset = bitsize_zero_node;
8861 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
8863 /* A reference to COMMON. */
8864 *decl = TREE_OPERAND (t, 0);
8865 *offset = bitsize_zero_node;
8870 /* Not a COMMON reference, so an unrecognized pattern. */
8871 *decl = error_mark_node;
8876 /* Given a tree that is possibly intended for use as an lvalue, return
8877 information representing a canonical view of that tree as a decl, an
8878 offset into that decl, and a size for the lvalue.
8880 If there's no applicable decl, NULL_TREE is returned for the decl,
8881 and the other fields are left undefined.
8883 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
8884 is returned for the decl, and the other fields are left undefined.
8886 Otherwise, the decl returned currently is either a VAR_DECL or a
8889 The offset returned is always valid, but of course not necessarily
8890 a constant, and not necessarily converted into the appropriate
8891 type, leaving that up to the caller (so as to avoid that overhead
8892 if the decls being looked at are different anyway).
8894 If the size cannot be determined (e.g. an adjustable array),
8895 an ERROR_MARK node is returned for the size. Otherwise, the
8896 size returned is valid, not necessarily a constant, and not
8897 necessarily converted into the appropriate type as with the
8900 Note that the offset and size expressions are expressed in the
8901 base storage units (usually bits) rather than in the units of
8902 the type of the decl, because two decls with different types
8903 might overlap but with apparently non-overlapping array offsets,
8904 whereas converting the array offsets to consistant offsets will
8905 reveal the overlap. */
8908 ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
8911 /* The default path is to report a nonexistant decl. */
8917 switch (TREE_CODE (t))
8920 case IDENTIFIER_NODE:
8929 case TRUNC_DIV_EXPR:
8931 case FLOOR_DIV_EXPR:
8932 case ROUND_DIV_EXPR:
8933 case TRUNC_MOD_EXPR:
8935 case FLOOR_MOD_EXPR:
8936 case ROUND_MOD_EXPR:
8938 case EXACT_DIV_EXPR:
8939 case FIX_TRUNC_EXPR:
8941 case FIX_FLOOR_EXPR:
8942 case FIX_ROUND_EXPR:
8956 case BIT_ANDTC_EXPR:
8958 case TRUTH_ANDIF_EXPR:
8959 case TRUTH_ORIF_EXPR:
8960 case TRUTH_AND_EXPR:
8962 case TRUTH_XOR_EXPR:
8963 case TRUTH_NOT_EXPR:
8983 *offset = bitsize_zero_node;
8984 *size = TYPE_SIZE (TREE_TYPE (t));
8989 tree array = TREE_OPERAND (t, 0);
8990 tree element = TREE_OPERAND (t, 1);
8993 if ((array == NULL_TREE)
8994 || (element == NULL_TREE))
8996 *decl = error_mark_node;
9000 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
9002 if ((*decl == NULL_TREE)
9003 || (*decl == error_mark_node))
9006 /* Calculate ((element - base) * NBBY) + init_offset. */
9007 *offset = fold (build (MINUS_EXPR, TREE_TYPE (element),
9009 TYPE_MIN_VALUE (TYPE_DOMAIN
9010 (TREE_TYPE (array)))));
9012 *offset = size_binop (MULT_EXPR,
9013 convert (bitsizetype, *offset),
9014 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))));
9016 *offset = size_binop (PLUS_EXPR, init_offset, *offset);
9018 *size = TYPE_SIZE (TREE_TYPE (t));
9024 /* Most of this code is to handle references to COMMON. And so
9025 far that is useful only for calling library functions, since
9026 external (user) functions might reference common areas. But
9027 even calling an external function, it's worthwhile to decode
9028 COMMON references because if not storing into COMMON, we don't
9029 want COMMON-based arguments to gratuitously force use of a
9032 *size = TYPE_SIZE (TREE_TYPE (t));
9034 ffecom_tree_canonize_ptr_ (decl, offset,
9035 TREE_OPERAND (t, 0));
9042 case NON_LVALUE_EXPR:
9045 case COND_EXPR: /* More cases than we can handle. */
9047 case REFERENCE_EXPR:
9048 case PREDECREMENT_EXPR:
9049 case PREINCREMENT_EXPR:
9050 case POSTDECREMENT_EXPR:
9051 case POSTINCREMENT_EXPR:
9054 *decl = error_mark_node;
9059 /* Do divide operation appropriate to type of operands. */
9062 ffecom_tree_divide_ (tree tree_type, tree left, tree right,
9063 tree dest_tree, ffebld dest, bool *dest_used,
9066 if ((left == error_mark_node)
9067 || (right == error_mark_node))
9068 return error_mark_node;
9070 switch (TREE_CODE (tree_type))
9073 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9078 if (! optimize_size)
9079 return ffecom_2 (RDIV_EXPR, tree_type,
9085 if (TREE_TYPE (tree_type)
9086 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9087 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9089 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9091 left = ffecom_1 (ADDR_EXPR,
9092 build_pointer_type (TREE_TYPE (left)),
9094 left = build_tree_list (NULL_TREE, left);
9095 right = ffecom_1 (ADDR_EXPR,
9096 build_pointer_type (TREE_TYPE (right)),
9098 right = build_tree_list (NULL_TREE, right);
9099 TREE_CHAIN (left) = right;
9101 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9102 ffecom_gfrt_kindtype (ix),
9103 ffe_is_f2c_library (),
9106 dest_tree, dest, dest_used,
9107 NULL_TREE, TRUE, hook);
9115 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9116 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9117 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9119 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9121 left = ffecom_1 (ADDR_EXPR,
9122 build_pointer_type (TREE_TYPE (left)),
9124 left = build_tree_list (NULL_TREE, left);
9125 right = ffecom_1 (ADDR_EXPR,
9126 build_pointer_type (TREE_TYPE (right)),
9128 right = build_tree_list (NULL_TREE, right);
9129 TREE_CHAIN (left) = right;
9131 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9132 ffecom_gfrt_kindtype (ix),
9133 ffe_is_f2c_library (),
9136 dest_tree, dest, dest_used,
9137 NULL_TREE, TRUE, hook);
9142 return ffecom_2 (RDIV_EXPR, tree_type,
9148 /* Build type info for non-dummy variable. */
9151 ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
9160 type = ffecom_tree_type[bt][kt];
9161 if (bt == FFEINFO_basictypeCHARACTER)
9163 hight = build_int_2 (ffesymbol_size (s), 0);
9164 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
9169 build_range_type (ffecom_f2c_ftnlen_type_node,
9170 ffecom_f2c_ftnlen_one_node,
9172 type = ffecom_check_size_overflow_ (s, type, FALSE);
9175 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9177 if (type == error_mark_node)
9180 dim = ffebld_head (dl);
9181 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
9183 if (ffebld_left (dim) == NULL)
9184 lowt = integer_one_node;
9186 lowt = ffecom_expr (ffebld_left (dim));
9188 if (TREE_CODE (lowt) != INTEGER_CST)
9189 lowt = variable_size (lowt);
9191 assert (ffebld_right (dim) != NULL);
9192 hight = ffecom_expr (ffebld_right (dim));
9194 if (TREE_CODE (hight) != INTEGER_CST)
9195 hight = variable_size (hight);
9197 type = build_array_type (type,
9198 build_range_type (ffecom_integer_type_node,
9200 type = ffecom_check_size_overflow_ (s, type, FALSE);
9206 /* Build Namelist type. */
9209 ffecom_type_namelist_ ()
9211 static tree type = NULL_TREE;
9213 if (type == NULL_TREE)
9215 static tree namefield, varsfield, nvarsfield;
9218 vardesctype = ffecom_type_vardesc_ ();
9220 type = make_node (RECORD_TYPE);
9222 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
9224 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9226 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9227 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9230 TYPE_FIELDS (type) = namefield;
9233 ggc_add_tree_root (&type, 1);
9239 /* Build Vardesc type. */
9242 ffecom_type_vardesc_ ()
9244 static tree type = NULL_TREE;
9245 static tree namefield, addrfield, dimsfield, typefield;
9247 if (type == NULL_TREE)
9249 type = make_node (RECORD_TYPE);
9251 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9253 addrfield = ffecom_decl_field (type, namefield, "addr",
9255 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9256 ffecom_f2c_ptr_to_ftnlen_type_node);
9257 typefield = ffecom_decl_field (type, dimsfield, "type",
9260 TYPE_FIELDS (type) = namefield;
9263 ggc_add_tree_root (&type, 1);
9270 ffecom_vardesc_ (ffebld expr)
9274 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9275 s = ffebld_symter (expr);
9277 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9280 tree vardesctype = ffecom_type_vardesc_ ();
9288 static int mynumber = 0;
9290 var = build_decl (VAR_DECL,
9291 ffecom_get_invented_identifier ("__g77_vardesc_%d",
9294 TREE_STATIC (var) = 1;
9295 DECL_INITIAL (var) = error_mark_node;
9297 var = start_decl (var, FALSE);
9299 /* Process inits. */
9301 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9303 ffesymbol_text (s));
9304 TREE_TYPE (nameinit)
9305 = build_type_variant
9308 build_range_type (integer_type_node,
9310 build_int_2 (i, 0))),
9312 TREE_CONSTANT (nameinit) = 1;
9313 TREE_STATIC (nameinit) = 1;
9314 nameinit = ffecom_1 (ADDR_EXPR,
9315 build_pointer_type (TREE_TYPE (nameinit)),
9318 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
9320 dimsinit = ffecom_vardesc_dims_ (s);
9322 if (typeinit == NULL_TREE)
9324 ffeinfoBasictype bt = ffesymbol_basictype (s);
9325 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9326 int tc = ffecom_f2c_typecode (bt, kt);
9329 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9332 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
9334 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9336 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9338 TREE_CHAIN (TREE_CHAIN (varinits))
9339 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9340 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9341 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
9343 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
9344 TREE_CONSTANT (varinits) = 1;
9345 TREE_STATIC (varinits) = 1;
9347 finish_decl (var, varinits, FALSE);
9349 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
9351 ffesymbol_hook (s).vardesc_tree = var;
9354 return ffesymbol_hook (s).vardesc_tree;
9358 ffecom_vardesc_array_ (ffesymbol s)
9362 tree item = NULL_TREE;
9365 static int mynumber = 0;
9367 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9369 b = ffebld_trail (b), ++i)
9373 t = ffecom_vardesc_ (ffebld_head (b));
9375 if (list == NULL_TREE)
9376 list = item = build_tree_list (NULL_TREE, t);
9379 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9380 item = TREE_CHAIN (item);
9384 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9385 build_range_type (integer_type_node,
9387 build_int_2 (i, 0)));
9388 list = build (CONSTRUCTOR, item, NULL_TREE, list);
9389 TREE_CONSTANT (list) = 1;
9390 TREE_STATIC (list) = 1;
9392 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber++);
9393 var = build_decl (VAR_DECL, var, item);
9394 TREE_STATIC (var) = 1;
9395 DECL_INITIAL (var) = error_mark_node;
9396 var = start_decl (var, FALSE);
9397 finish_decl (var, list, FALSE);
9403 ffecom_vardesc_dims_ (ffesymbol s)
9405 if (ffesymbol_dims (s) == NULL)
9406 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9414 tree item = NULL_TREE;
9418 tree baseoff = NULL_TREE;
9419 static int mynumber = 0;
9421 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9422 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9424 numelem = ffecom_expr (ffesymbol_arraysize (s));
9425 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9428 backlist = NULL_TREE;
9429 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9431 b = ffebld_trail (b), e = ffebld_trail (e))
9437 if (ffebld_trail (b) == NULL)
9441 t = convert (ffecom_f2c_ftnlen_type_node,
9442 ffecom_expr (ffebld_head (e)));
9444 if (list == NULL_TREE)
9445 list = item = build_tree_list (NULL_TREE, t);
9448 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9449 item = TREE_CHAIN (item);
9453 if (ffebld_left (ffebld_head (b)) == NULL)
9454 low = ffecom_integer_one_node;
9456 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9457 low = convert (ffecom_f2c_ftnlen_type_node, low);
9459 back = build_tree_list (low, t);
9460 TREE_CHAIN (back) = backlist;
9464 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9466 if (TREE_VALUE (item) == NULL_TREE)
9467 baseoff = TREE_PURPOSE (item);
9469 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9470 TREE_PURPOSE (item),
9471 ffecom_2 (MULT_EXPR,
9472 ffecom_f2c_ftnlen_type_node,
9477 /* backlist now dead, along with all TREE_PURPOSEs on it. */
9479 baseoff = build_tree_list (NULL_TREE, baseoff);
9480 TREE_CHAIN (baseoff) = list;
9482 numelem = build_tree_list (NULL_TREE, numelem);
9483 TREE_CHAIN (numelem) = baseoff;
9485 numdim = build_tree_list (NULL_TREE, numdim);
9486 TREE_CHAIN (numdim) = numelem;
9488 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9489 build_range_type (integer_type_node,
9492 ((int) ffesymbol_rank (s)
9494 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
9495 TREE_CONSTANT (list) = 1;
9496 TREE_STATIC (list) = 1;
9498 var = ffecom_get_invented_identifier ("__g77_dims_%d", mynumber++);
9499 var = build_decl (VAR_DECL, var, item);
9500 TREE_STATIC (var) = 1;
9501 DECL_INITIAL (var) = error_mark_node;
9502 var = start_decl (var, FALSE);
9503 finish_decl (var, list, FALSE);
9505 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9511 /* Essentially does a "fold (build1 (code, type, node))" while checking
9512 for certain housekeeping things.
9514 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9515 ffecom_1_fn instead. */
9518 ffecom_1 (enum tree_code code, tree type, tree node)
9522 if ((node == error_mark_node)
9523 || (type == error_mark_node))
9524 return error_mark_node;
9526 if (code == ADDR_EXPR)
9528 if (!mark_addressable (node))
9529 assert ("can't mark_addressable this node!" == NULL);
9532 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9537 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
9541 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9546 if (TREE_CODE (type) != RECORD_TYPE)
9548 item = build1 (code, type, node);
9551 node = ffecom_stabilize_aggregate_ (node);
9552 realtype = TREE_TYPE (TYPE_FIELDS (type));
9554 ffecom_2 (COMPLEX_EXPR, type,
9555 ffecom_1 (NEGATE_EXPR, realtype,
9556 ffecom_1 (REALPART_EXPR, realtype,
9558 ffecom_1 (NEGATE_EXPR, realtype,
9559 ffecom_1 (IMAGPART_EXPR, realtype,
9564 item = build1 (code, type, node);
9568 if (TREE_SIDE_EFFECTS (node))
9569 TREE_SIDE_EFFECTS (item) = 1;
9570 if (code == ADDR_EXPR && staticp (node))
9571 TREE_CONSTANT (item) = 1;
9572 else if (code == INDIRECT_REF)
9573 TREE_READONLY (item) = TYPE_READONLY (type);
9577 /* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9578 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9579 does not set TREE_ADDRESSABLE (because calling an inline
9580 function does not mean the function needs to be separately
9584 ffecom_1_fn (tree node)
9589 if (node == error_mark_node)
9590 return error_mark_node;
9592 type = build_type_variant (TREE_TYPE (node),
9593 TREE_READONLY (node),
9594 TREE_THIS_VOLATILE (node));
9595 item = build1 (ADDR_EXPR,
9596 build_pointer_type (type), node);
9597 if (TREE_SIDE_EFFECTS (node))
9598 TREE_SIDE_EFFECTS (item) = 1;
9600 TREE_CONSTANT (item) = 1;
9604 /* Essentially does a "fold (build (code, type, node1, node2))" while
9605 checking for certain housekeeping things. */
9608 ffecom_2 (enum tree_code code, tree type, tree node1,
9613 if ((node1 == error_mark_node)
9614 || (node2 == error_mark_node)
9615 || (type == error_mark_node))
9616 return error_mark_node;
9618 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9620 tree a, b, c, d, realtype;
9623 assert ("no CONJ_EXPR support yet" == NULL);
9624 return error_mark_node;
9627 item = build_tree_list (TYPE_FIELDS (type), node1);
9628 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9629 item = build (CONSTRUCTOR, type, NULL_TREE, item);
9633 if (TREE_CODE (type) != RECORD_TYPE)
9635 item = build (code, type, node1, node2);
9638 node1 = ffecom_stabilize_aggregate_ (node1);
9639 node2 = ffecom_stabilize_aggregate_ (node2);
9640 realtype = TREE_TYPE (TYPE_FIELDS (type));
9642 ffecom_2 (COMPLEX_EXPR, type,
9643 ffecom_2 (PLUS_EXPR, realtype,
9644 ffecom_1 (REALPART_EXPR, realtype,
9646 ffecom_1 (REALPART_EXPR, realtype,
9648 ffecom_2 (PLUS_EXPR, realtype,
9649 ffecom_1 (IMAGPART_EXPR, realtype,
9651 ffecom_1 (IMAGPART_EXPR, realtype,
9656 if (TREE_CODE (type) != RECORD_TYPE)
9658 item = build (code, type, node1, node2);
9661 node1 = ffecom_stabilize_aggregate_ (node1);
9662 node2 = ffecom_stabilize_aggregate_ (node2);
9663 realtype = TREE_TYPE (TYPE_FIELDS (type));
9665 ffecom_2 (COMPLEX_EXPR, type,
9666 ffecom_2 (MINUS_EXPR, realtype,
9667 ffecom_1 (REALPART_EXPR, realtype,
9669 ffecom_1 (REALPART_EXPR, realtype,
9671 ffecom_2 (MINUS_EXPR, realtype,
9672 ffecom_1 (IMAGPART_EXPR, realtype,
9674 ffecom_1 (IMAGPART_EXPR, realtype,
9679 if (TREE_CODE (type) != RECORD_TYPE)
9681 item = build (code, type, node1, node2);
9684 node1 = ffecom_stabilize_aggregate_ (node1);
9685 node2 = ffecom_stabilize_aggregate_ (node2);
9686 realtype = TREE_TYPE (TYPE_FIELDS (type));
9687 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9689 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9691 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9693 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9696 ffecom_2 (COMPLEX_EXPR, type,
9697 ffecom_2 (MINUS_EXPR, realtype,
9698 ffecom_2 (MULT_EXPR, realtype,
9701 ffecom_2 (MULT_EXPR, realtype,
9704 ffecom_2 (PLUS_EXPR, realtype,
9705 ffecom_2 (MULT_EXPR, realtype,
9708 ffecom_2 (MULT_EXPR, realtype,
9714 if ((TREE_CODE (node1) != RECORD_TYPE)
9715 && (TREE_CODE (node2) != RECORD_TYPE))
9717 item = build (code, type, node1, node2);
9720 assert (TREE_CODE (node1) == RECORD_TYPE);
9721 assert (TREE_CODE (node2) == RECORD_TYPE);
9722 node1 = ffecom_stabilize_aggregate_ (node1);
9723 node2 = ffecom_stabilize_aggregate_ (node2);
9724 realtype = TREE_TYPE (TYPE_FIELDS (type));
9726 ffecom_2 (TRUTH_ANDIF_EXPR, type,
9727 ffecom_2 (code, type,
9728 ffecom_1 (REALPART_EXPR, realtype,
9730 ffecom_1 (REALPART_EXPR, realtype,
9732 ffecom_2 (code, type,
9733 ffecom_1 (IMAGPART_EXPR, realtype,
9735 ffecom_1 (IMAGPART_EXPR, realtype,
9740 if ((TREE_CODE (node1) != RECORD_TYPE)
9741 && (TREE_CODE (node2) != RECORD_TYPE))
9743 item = build (code, type, node1, node2);
9746 assert (TREE_CODE (node1) == RECORD_TYPE);
9747 assert (TREE_CODE (node2) == RECORD_TYPE);
9748 node1 = ffecom_stabilize_aggregate_ (node1);
9749 node2 = ffecom_stabilize_aggregate_ (node2);
9750 realtype = TREE_TYPE (TYPE_FIELDS (type));
9752 ffecom_2 (TRUTH_ORIF_EXPR, type,
9753 ffecom_2 (code, type,
9754 ffecom_1 (REALPART_EXPR, realtype,
9756 ffecom_1 (REALPART_EXPR, realtype,
9758 ffecom_2 (code, type,
9759 ffecom_1 (IMAGPART_EXPR, realtype,
9761 ffecom_1 (IMAGPART_EXPR, realtype,
9766 item = build (code, type, node1, node2);
9770 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
9771 TREE_SIDE_EFFECTS (item) = 1;
9775 /* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
9777 ffesymbol s; // the ENTRY point itself
9778 if (ffecom_2pass_advise_entrypoint(s))
9779 // the ENTRY point has been accepted
9781 Does whatever compiler needs to do when it learns about the entrypoint,
9782 like determine the return type of the master function, count the
9783 number of entrypoints, etc. Returns FALSE if the return type is
9784 not compatible with the return type(s) of other entrypoint(s).
9786 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
9787 later (after _finish_progunit) be called with the same entrypoint(s)
9788 as passed to this fn for which TRUE was returned.
9791 Return FALSE if the return type conflicts with previous entrypoints. */
9794 ffecom_2pass_advise_entrypoint (ffesymbol entry)
9796 ffebld list; /* opITEM. */
9797 ffebld mlist; /* opITEM. */
9798 ffebld plist; /* opITEM. */
9799 ffebld arg; /* ffebld_head(opITEM). */
9800 ffebld item; /* opITEM. */
9801 ffesymbol s; /* ffebld_symter(arg). */
9802 ffeinfoBasictype bt = ffesymbol_basictype (entry);
9803 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
9804 ffetargetCharacterSize size = ffesymbol_size (entry);
9807 if (ffecom_num_entrypoints_ == 0)
9808 { /* First entrypoint, make list of main
9809 arglist's dummies. */
9810 assert (ffecom_primary_entry_ != NULL);
9812 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
9813 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
9814 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
9816 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
9818 list = ffebld_trail (list))
9820 arg = ffebld_head (list);
9821 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9822 continue; /* Alternate return or some such thing. */
9823 item = ffebld_new_item (arg, NULL);
9825 ffecom_master_arglist_ = item;
9827 ffebld_set_trail (plist, item);
9832 /* If necessary, scan entry arglist for alternate returns. Do this scan
9833 apparently redundantly (it's done below to UNIONize the arglists) so
9834 that we don't complain about RETURN 1 if an offending ENTRY is the only
9835 one with an alternate return. */
9837 if (!ffecom_is_altreturning_)
9839 for (list = ffesymbol_dummyargs (entry);
9841 list = ffebld_trail (list))
9843 arg = ffebld_head (list);
9844 if (ffebld_op (arg) == FFEBLD_opSTAR)
9846 ffecom_is_altreturning_ = TRUE;
9852 /* Now check type compatibility. */
9854 switch (ffecom_master_bt_)
9856 case FFEINFO_basictypeNONE:
9857 ok = (bt != FFEINFO_basictypeCHARACTER);
9860 case FFEINFO_basictypeCHARACTER:
9862 = (bt == FFEINFO_basictypeCHARACTER)
9863 && (kt == ffecom_master_kt_)
9864 && (size == ffecom_master_size_);
9867 case FFEINFO_basictypeANY:
9868 return FALSE; /* Just don't bother. */
9871 if (bt == FFEINFO_basictypeCHARACTER)
9877 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
9879 ffecom_master_bt_ = FFEINFO_basictypeNONE;
9880 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
9887 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
9888 ffest_ffebad_here_current_stmt (0);
9890 return FALSE; /* Can't handle entrypoint. */
9893 /* Entrypoint type compatible with previous types. */
9895 ++ffecom_num_entrypoints_;
9897 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
9899 for (list = ffesymbol_dummyargs (entry);
9901 list = ffebld_trail (list))
9903 arg = ffebld_head (list);
9904 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9905 continue; /* Alternate return or some such thing. */
9906 s = ffebld_symter (arg);
9907 for (plist = NULL, mlist = ffecom_master_arglist_;
9909 plist = mlist, mlist = ffebld_trail (mlist))
9910 { /* plist points to previous item for easy
9911 appending of arg. */
9912 if (ffebld_symter (ffebld_head (mlist)) == s)
9913 break; /* Already have this arg in the master list. */
9916 continue; /* Already have this arg in the master list. */
9918 /* Append this arg to the master list. */
9920 item = ffebld_new_item (arg, NULL);
9922 ffecom_master_arglist_ = item;
9924 ffebld_set_trail (plist, item);
9930 /* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
9932 ffesymbol s; // the ENTRY point itself
9933 ffecom_2pass_do_entrypoint(s);
9935 Does whatever compiler needs to do to make the entrypoint actually
9936 happen. Must be called for each entrypoint after
9937 ffecom_finish_progunit is called. */
9940 ffecom_2pass_do_entrypoint (ffesymbol entry)
9942 static int mfn_num = 0;
9945 if (mfn_num != ffecom_num_fns_)
9946 { /* First entrypoint for this program unit. */
9948 mfn_num = ffecom_num_fns_;
9949 ffecom_do_entry_ (ffecom_primary_entry_, 0);
9954 --ffecom_num_entrypoints_;
9956 ffecom_do_entry_ (entry, ent_num);
9959 /* Essentially does a "fold (build (code, type, node1, node2))" while
9960 checking for certain housekeeping things. Always sets
9961 TREE_SIDE_EFFECTS. */
9964 ffecom_2s (enum tree_code code, tree type, tree node1,
9969 if ((node1 == error_mark_node)
9970 || (node2 == error_mark_node)
9971 || (type == error_mark_node))
9972 return error_mark_node;
9974 item = build (code, type, node1, node2);
9975 TREE_SIDE_EFFECTS (item) = 1;
9979 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
9980 checking for certain housekeeping things. */
9983 ffecom_3 (enum tree_code code, tree type, tree node1,
9984 tree node2, tree node3)
9988 if ((node1 == error_mark_node)
9989 || (node2 == error_mark_node)
9990 || (node3 == error_mark_node)
9991 || (type == error_mark_node))
9992 return error_mark_node;
9994 item = build (code, type, node1, node2, node3);
9995 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
9996 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
9997 TREE_SIDE_EFFECTS (item) = 1;
10001 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10002 checking for certain housekeeping things. Always sets
10003 TREE_SIDE_EFFECTS. */
10006 ffecom_3s (enum tree_code code, tree type, tree node1,
10007 tree node2, tree node3)
10011 if ((node1 == error_mark_node)
10012 || (node2 == error_mark_node)
10013 || (node3 == error_mark_node)
10014 || (type == error_mark_node))
10015 return error_mark_node;
10017 item = build (code, type, node1, node2, node3);
10018 TREE_SIDE_EFFECTS (item) = 1;
10019 return fold (item);
10022 /* ffecom_arg_expr -- Transform argument expr into gcc tree
10024 See use by ffecom_list_expr.
10026 If expression is NULL, returns an integer zero tree. If it is not
10027 a CHARACTER expression, returns whatever ffecom_expr
10028 returns and sets the length return value to NULL_TREE. Otherwise
10029 generates code to evaluate the character expression, returns the proper
10030 pointer to the result, but does NOT set the length return value to a tree
10031 that specifies the length of the result. (In other words, the length
10032 variable is always set to NULL_TREE, because a length is never passed.)
10035 Don't set returned length, since nobody needs it (yet; someday if
10036 we allow CHARACTER*(*) dummies to statement functions, we'll need
10040 ffecom_arg_expr (ffebld expr, tree *length)
10044 *length = NULL_TREE;
10047 return integer_zero_node;
10049 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10050 return ffecom_expr (expr);
10052 return ffecom_arg_ptr_to_expr (expr, &ign);
10055 /* Transform expression into constant argument-pointer-to-expression tree.
10057 If the expression can be transformed into a argument-pointer-to-expression
10058 tree that is constant, that is done, and the tree returned. Else
10059 NULL_TREE is returned.
10061 That way, a caller can attempt to provide compile-time initialization
10062 of a variable and, if that fails, *then* choose to start a new block
10063 and resort to using temporaries, as appropriate. */
10066 ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10069 return integer_zero_node;
10071 if (ffebld_op (expr) == FFEBLD_opANY)
10074 *length = error_mark_node;
10075 return error_mark_node;
10078 if (ffebld_arity (expr) == 0
10079 && (ffebld_op (expr) != FFEBLD_opSYMTER
10080 || ffebld_where (expr) == FFEINFO_whereCOMMON
10081 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10082 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10086 t = ffecom_arg_ptr_to_expr (expr, length);
10087 assert (TREE_CONSTANT (t));
10088 assert (! length || TREE_CONSTANT (*length));
10093 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10094 *length = build_int_2 (ffebld_size (expr), 0);
10096 *length = NULL_TREE;
10100 /* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
10102 See use by ffecom_list_ptr_to_expr.
10104 If expression is NULL, returns an integer zero tree. If it is not
10105 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10106 returns and sets the length return value to NULL_TREE. Otherwise
10107 generates code to evaluate the character expression, returns the proper
10108 pointer to the result, AND sets the length return value to a tree that
10109 specifies the length of the result.
10111 If the length argument is NULL, this is a slightly special
10112 case of building a FORMAT expression, that is, an expression that
10113 will be used at run time without regard to length. For the current
10114 implementation, which uses the libf2c library, this means it is nice
10115 to append a null byte to the end of the expression, where feasible,
10116 to make sure any diagnostic about the FORMAT string terminates at
10119 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10120 length argument. This might even be seen as a feature, if a null
10121 byte can always be appended. */
10124 ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
10128 ffecomConcatList_ catlist;
10130 if (length != NULL)
10131 *length = NULL_TREE;
10134 return integer_zero_node;
10136 switch (ffebld_op (expr))
10138 case FFEBLD_opPERCENT_VAL:
10139 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10140 return ffecom_expr (ffebld_left (expr));
10145 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10146 if (temp_exp == error_mark_node)
10147 return error_mark_node;
10149 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10153 case FFEBLD_opPERCENT_REF:
10154 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10155 return ffecom_ptr_to_expr (ffebld_left (expr));
10156 if (length != NULL)
10158 ign_length = NULL_TREE;
10159 length = &ign_length;
10161 expr = ffebld_left (expr);
10164 case FFEBLD_opPERCENT_DESCR:
10165 switch (ffeinfo_basictype (ffebld_info (expr)))
10167 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10168 case FFEINFO_basictypeHOLLERITH:
10170 case FFEINFO_basictypeCHARACTER:
10171 break; /* Passed by descriptor anyway. */
10174 item = ffecom_ptr_to_expr (expr);
10175 if (item != error_mark_node)
10176 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
10185 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10186 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10187 && (length != NULL))
10188 { /* Pass Hollerith by descriptor. */
10189 ffetargetHollerith h;
10191 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10192 h = ffebld_cu_val_hollerith (ffebld_constant_union
10193 (ffebld_conter (expr)));
10195 = build_int_2 (h.length, 0);
10196 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10200 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10201 return ffecom_ptr_to_expr (expr);
10203 assert (ffeinfo_kindtype (ffebld_info (expr))
10204 == FFEINFO_kindtypeCHARACTER1);
10206 while (ffebld_op (expr) == FFEBLD_opPAREN)
10207 expr = ffebld_left (expr);
10209 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10210 switch (ffecom_concat_list_count_ (catlist))
10212 case 0: /* Shouldn't happen, but in case it does... */
10213 if (length != NULL)
10215 *length = ffecom_f2c_ftnlen_zero_node;
10216 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10218 ffecom_concat_list_kill_ (catlist);
10219 return null_pointer_node;
10221 case 1: /* The (fairly) easy case. */
10222 if (length == NULL)
10223 ffecom_char_args_with_null_ (&item, &ign_length,
10224 ffecom_concat_list_expr_ (catlist, 0));
10226 ffecom_char_args_ (&item, length,
10227 ffecom_concat_list_expr_ (catlist, 0));
10228 ffecom_concat_list_kill_ (catlist);
10229 assert (item != NULL_TREE);
10232 default: /* Must actually concatenate things. */
10237 int count = ffecom_concat_list_count_ (catlist);
10248 ffetargetCharacterSize sz;
10250 sz = ffecom_concat_list_maxlen_ (catlist);
10252 assert (sz != FFETARGET_charactersizeNONE);
10257 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10258 FFETARGET_charactersizeNONE, count, TRUE);
10261 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10262 FFETARGET_charactersizeNONE, count, TRUE);
10263 temporary = ffecom_push_tempvar (char_type_node,
10269 hook = ffebld_nonter_hook (expr);
10271 assert (TREE_CODE (hook) == TREE_VEC);
10272 assert (TREE_VEC_LENGTH (hook) == 3);
10273 length_array = lengths = TREE_VEC_ELT (hook, 0);
10274 item_array = items = TREE_VEC_ELT (hook, 1);
10275 temporary = TREE_VEC_ELT (hook, 2);
10279 known_length = ffecom_f2c_ftnlen_zero_node;
10281 for (i = 0; i < count; ++i)
10284 && (length == NULL))
10285 ffecom_char_args_with_null_ (&citem, &clength,
10286 ffecom_concat_list_expr_ (catlist, i));
10288 ffecom_char_args_ (&citem, &clength,
10289 ffecom_concat_list_expr_ (catlist, i));
10290 if ((citem == error_mark_node)
10291 || (clength == error_mark_node))
10293 ffecom_concat_list_kill_ (catlist);
10294 *length = error_mark_node;
10295 return error_mark_node;
10299 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10300 ffecom_modify (void_type_node,
10301 ffecom_2 (ARRAY_REF,
10302 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10304 build_int_2 (i, 0)),
10307 clength = ffecom_save_tree (clength);
10308 if (length != NULL)
10310 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10314 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10315 ffecom_modify (void_type_node,
10316 ffecom_2 (ARRAY_REF,
10317 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10319 build_int_2 (i, 0)),
10324 temporary = ffecom_1 (ADDR_EXPR,
10325 build_pointer_type (TREE_TYPE (temporary)),
10328 item = build_tree_list (NULL_TREE, temporary);
10330 = build_tree_list (NULL_TREE,
10331 ffecom_1 (ADDR_EXPR,
10332 build_pointer_type (TREE_TYPE (items)),
10334 TREE_CHAIN (TREE_CHAIN (item))
10335 = build_tree_list (NULL_TREE,
10336 ffecom_1 (ADDR_EXPR,
10337 build_pointer_type (TREE_TYPE (lengths)),
10339 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10342 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10343 convert (ffecom_f2c_ftnlen_type_node,
10344 build_int_2 (count, 0))));
10345 num = build_int_2 (sz, 0);
10346 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10347 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10348 = build_tree_list (NULL_TREE, num);
10350 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
10351 TREE_SIDE_EFFECTS (item) = 1;
10352 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10356 if (length != NULL)
10357 *length = known_length;
10360 ffecom_concat_list_kill_ (catlist);
10361 assert (item != NULL_TREE);
10365 /* Generate call to run-time function.
10367 The first arg is the GNU Fortran Run-Time function index, the second
10368 arg is the list of arguments to pass to it. Returned is the expression
10369 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10370 result (which may be void). */
10373 ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
10375 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10376 ffecom_gfrt_kindtype (ix),
10377 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10378 NULL_TREE, args, NULL_TREE, NULL,
10379 NULL, NULL_TREE, TRUE, hook);
10382 /* Transform constant-union to tree. */
10385 ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10386 ffeinfoKindtype kt, tree tree_type)
10392 case FFEINFO_basictypeINTEGER:
10398 #if FFETARGET_okINTEGER1
10399 case FFEINFO_kindtypeINTEGER1:
10400 val = ffebld_cu_val_integer1 (*cu);
10404 #if FFETARGET_okINTEGER2
10405 case FFEINFO_kindtypeINTEGER2:
10406 val = ffebld_cu_val_integer2 (*cu);
10410 #if FFETARGET_okINTEGER3
10411 case FFEINFO_kindtypeINTEGER3:
10412 val = ffebld_cu_val_integer3 (*cu);
10416 #if FFETARGET_okINTEGER4
10417 case FFEINFO_kindtypeINTEGER4:
10418 val = ffebld_cu_val_integer4 (*cu);
10423 assert ("bad INTEGER constant kind type" == NULL);
10424 /* Fall through. */
10425 case FFEINFO_kindtypeANY:
10426 return error_mark_node;
10428 item = build_int_2 (val, (val < 0) ? -1 : 0);
10429 TREE_TYPE (item) = tree_type;
10433 case FFEINFO_basictypeLOGICAL:
10439 #if FFETARGET_okLOGICAL1
10440 case FFEINFO_kindtypeLOGICAL1:
10441 val = ffebld_cu_val_logical1 (*cu);
10445 #if FFETARGET_okLOGICAL2
10446 case FFEINFO_kindtypeLOGICAL2:
10447 val = ffebld_cu_val_logical2 (*cu);
10451 #if FFETARGET_okLOGICAL3
10452 case FFEINFO_kindtypeLOGICAL3:
10453 val = ffebld_cu_val_logical3 (*cu);
10457 #if FFETARGET_okLOGICAL4
10458 case FFEINFO_kindtypeLOGICAL4:
10459 val = ffebld_cu_val_logical4 (*cu);
10464 assert ("bad LOGICAL constant kind type" == NULL);
10465 /* Fall through. */
10466 case FFEINFO_kindtypeANY:
10467 return error_mark_node;
10469 item = build_int_2 (val, (val < 0) ? -1 : 0);
10470 TREE_TYPE (item) = tree_type;
10474 case FFEINFO_basictypeREAL:
10476 REAL_VALUE_TYPE val;
10480 #if FFETARGET_okREAL1
10481 case FFEINFO_kindtypeREAL1:
10482 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10486 #if FFETARGET_okREAL2
10487 case FFEINFO_kindtypeREAL2:
10488 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10492 #if FFETARGET_okREAL3
10493 case FFEINFO_kindtypeREAL3:
10494 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10498 #if FFETARGET_okREAL4
10499 case FFEINFO_kindtypeREAL4:
10500 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10505 assert ("bad REAL constant kind type" == NULL);
10506 /* Fall through. */
10507 case FFEINFO_kindtypeANY:
10508 return error_mark_node;
10510 item = build_real (tree_type, val);
10514 case FFEINFO_basictypeCOMPLEX:
10516 REAL_VALUE_TYPE real;
10517 REAL_VALUE_TYPE imag;
10518 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
10522 #if FFETARGET_okCOMPLEX1
10523 case FFEINFO_kindtypeREAL1:
10524 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10525 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10529 #if FFETARGET_okCOMPLEX2
10530 case FFEINFO_kindtypeREAL2:
10531 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10532 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10536 #if FFETARGET_okCOMPLEX3
10537 case FFEINFO_kindtypeREAL3:
10538 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10539 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10543 #if FFETARGET_okCOMPLEX4
10544 case FFEINFO_kindtypeREAL4:
10545 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10546 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10551 assert ("bad REAL constant kind type" == NULL);
10552 /* Fall through. */
10553 case FFEINFO_kindtypeANY:
10554 return error_mark_node;
10556 item = ffecom_build_complex_constant_ (tree_type,
10557 build_real (el_type, real),
10558 build_real (el_type, imag));
10562 case FFEINFO_basictypeCHARACTER:
10563 { /* Happens only in DATA and similar contexts. */
10564 ffetargetCharacter1 val;
10568 #if FFETARGET_okCHARACTER1
10569 case FFEINFO_kindtypeLOGICAL1:
10570 val = ffebld_cu_val_character1 (*cu);
10575 assert ("bad CHARACTER constant kind type" == NULL);
10576 /* Fall through. */
10577 case FFEINFO_kindtypeANY:
10578 return error_mark_node;
10580 item = build_string (ffetarget_length_character1 (val),
10581 ffetarget_text_character1 (val));
10583 = build_type_variant (build_array_type (char_type_node,
10585 (integer_type_node,
10588 (ffetarget_length_character1
10594 case FFEINFO_basictypeHOLLERITH:
10596 ffetargetHollerith h;
10598 h = ffebld_cu_val_hollerith (*cu);
10600 /* If not at least as wide as default INTEGER, widen it. */
10601 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10602 item = build_string (h.length, h.text);
10605 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
10607 memcpy (str, h.text, h.length);
10608 memset (&str[h.length], ' ',
10609 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10611 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10615 = build_type_variant (build_array_type (char_type_node,
10617 (integer_type_node,
10625 case FFEINFO_basictypeTYPELESS:
10627 ffetargetInteger1 ival;
10628 ffetargetTypeless tless;
10631 tless = ffebld_cu_val_typeless (*cu);
10632 error = ffetarget_convert_integer1_typeless (&ival, tless);
10633 assert (error == FFEBAD);
10635 item = build_int_2 ((int) ival, 0);
10640 assert ("not yet on constant type" == NULL);
10641 /* Fall through. */
10642 case FFEINFO_basictypeANY:
10643 return error_mark_node;
10646 TREE_CONSTANT (item) = 1;
10651 /* Transform expression into constant tree.
10653 If the expression can be transformed into a tree that is constant,
10654 that is done, and the tree returned. Else NULL_TREE is returned.
10656 That way, a caller can attempt to provide compile-time initialization
10657 of a variable and, if that fails, *then* choose to start a new block
10658 and resort to using temporaries, as appropriate. */
10661 ffecom_const_expr (ffebld expr)
10664 return integer_zero_node;
10666 if (ffebld_op (expr) == FFEBLD_opANY)
10667 return error_mark_node;
10669 if (ffebld_arity (expr) == 0
10670 && (ffebld_op (expr) != FFEBLD_opSYMTER
10672 /* ~~Enable once common/equivalence is handled properly? */
10673 || ffebld_where (expr) == FFEINFO_whereCOMMON
10675 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10676 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10680 t = ffecom_expr (expr);
10681 assert (TREE_CONSTANT (t));
10688 /* Handy way to make a field in a struct/union. */
10691 ffecom_decl_field (tree context, tree prevfield,
10692 const char *name, tree type)
10696 field = build_decl (FIELD_DECL, get_identifier (name), type);
10697 DECL_CONTEXT (field) = context;
10698 DECL_ALIGN (field) = 0;
10699 DECL_USER_ALIGN (field) = 0;
10700 if (prevfield != NULL_TREE)
10701 TREE_CHAIN (prevfield) = field;
10707 ffecom_close_include (FILE *f)
10709 ffecom_close_include_ (f);
10713 ffecom_decode_include_option (char *spec)
10715 return ffecom_decode_include_option_ (spec);
10718 /* End a compound statement (block). */
10721 ffecom_end_compstmt (void)
10723 return bison_rule_compstmt_ ();
10726 /* ffecom_end_transition -- Perform end transition on all symbols
10728 ffecom_end_transition();
10730 Calls ffecom_sym_end_transition for each global and local symbol. */
10733 ffecom_end_transition ()
10737 if (ffe_is_ffedebug ())
10738 fprintf (dmpout, "; end_stmt_transition\n");
10740 ffecom_list_blockdata_ = NULL;
10741 ffecom_list_common_ = NULL;
10743 ffesymbol_drive (ffecom_sym_end_transition);
10744 if (ffe_is_ffedebug ())
10746 ffestorag_report ();
10749 ffecom_start_progunit_ ();
10751 for (item = ffecom_list_blockdata_;
10753 item = ffebld_trail (item))
10760 static int number = 0;
10762 callee = ffebld_head (item);
10763 s = ffebld_symter (callee);
10764 t = ffesymbol_hook (s).decl_tree;
10765 if (t == NULL_TREE)
10767 s = ffecom_sym_transform_ (s);
10768 t = ffesymbol_hook (s).decl_tree;
10771 dt = build_pointer_type (TREE_TYPE (t));
10773 var = build_decl (VAR_DECL,
10774 ffecom_get_invented_identifier ("__g77_forceload_%d",
10777 DECL_EXTERNAL (var) = 0;
10778 TREE_STATIC (var) = 1;
10779 TREE_PUBLIC (var) = 0;
10780 DECL_INITIAL (var) = error_mark_node;
10781 TREE_USED (var) = 1;
10783 var = start_decl (var, FALSE);
10785 t = ffecom_1 (ADDR_EXPR, dt, t);
10787 finish_decl (var, t, FALSE);
10790 /* This handles any COMMON areas that weren't referenced but have, for
10791 example, important initial data. */
10793 for (item = ffecom_list_common_;
10795 item = ffebld_trail (item))
10796 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
10798 ffecom_list_common_ = NULL;
10801 /* ffecom_exec_transition -- Perform exec transition on all symbols
10803 ffecom_exec_transition();
10805 Calls ffecom_sym_exec_transition for each global and local symbol.
10806 Make sure error updating not inhibited. */
10809 ffecom_exec_transition ()
10813 if (ffe_is_ffedebug ())
10814 fprintf (dmpout, "; exec_stmt_transition\n");
10816 inhibited = ffebad_inhibit ();
10817 ffebad_set_inhibit (FALSE);
10819 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
10820 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
10821 if (ffe_is_ffedebug ())
10823 ffestorag_report ();
10827 ffebad_set_inhibit (TRUE);
10830 /* Handle assignment statement.
10832 Convert dest and source using ffecom_expr, then join them
10833 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
10836 ffecom_expand_let_stmt (ffebld dest, ffebld source)
10843 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
10848 /* This attempts to replicate the test below, but must not be
10849 true when the test below is false. (Always err on the side
10850 of creating unused temporaries, to avoid ICEs.) */
10851 if (ffebld_op (dest) != FFEBLD_opSYMTER
10852 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
10853 && (TREE_CODE (dest_tree) != VAR_DECL
10854 || TREE_ADDRESSABLE (dest_tree))))
10856 ffecom_prepare_expr_ (source, dest);
10861 ffecom_prepare_expr_ (source, NULL);
10865 ffecom_prepare_expr_w (NULL_TREE, dest);
10867 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
10868 create a temporary through which the assignment is to take place,
10869 since MODIFY_EXPR doesn't handle partial overlap properly. */
10870 if (ffebld_basictype (dest) == FFEINFO_basictypeCOMPLEX
10871 && ffecom_possible_partial_overlap_ (dest, source))
10873 assign_temp = ffecom_make_tempvar ("complex_let",
10875 [ffebld_basictype (dest)]
10876 [ffebld_kindtype (dest)],
10877 FFETARGET_charactersizeNONE,
10881 assign_temp = NULL_TREE;
10883 ffecom_prepare_end ();
10885 dest_tree = ffecom_expr_w (NULL_TREE, dest);
10886 if (dest_tree == error_mark_node)
10889 if ((TREE_CODE (dest_tree) != VAR_DECL)
10890 || TREE_ADDRESSABLE (dest_tree))
10891 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
10895 assert (! dest_used);
10897 source_tree = ffecom_expr (source);
10899 if (source_tree == error_mark_node)
10903 expr_tree = source_tree;
10904 else if (assign_temp)
10907 /* The back end understands a conceptual move (evaluate source;
10908 store into dest), so use that, in case it can determine
10909 that it is going to use, say, two registers as temporaries
10910 anyway. So don't use the temp (and someday avoid generating
10911 it, once this code starts triggering regularly). */
10912 expr_tree = ffecom_2s (MOVE_EXPR, void_type_node,
10916 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10919 expand_expr_stmt (expr_tree);
10920 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10926 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10930 expand_expr_stmt (expr_tree);
10934 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
10935 ffecom_prepare_expr_w (NULL_TREE, dest);
10937 ffecom_prepare_end ();
10939 ffecom_char_args_ (&dest_tree, &dest_length, dest);
10940 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
10944 /* ffecom_expr -- Transform expr into gcc tree
10947 ffebld expr; // FFE expression.
10948 tree = ffecom_expr(expr);
10950 Recursive descent on expr while making corresponding tree nodes and
10951 attaching type info and such. */
10954 ffecom_expr (ffebld expr)
10956 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
10959 /* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
10962 ffecom_expr_assign (ffebld expr)
10964 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10967 /* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
10970 ffecom_expr_assign_w (ffebld expr)
10972 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10975 /* Transform expr for use as into read/write tree and stabilize the
10976 reference. Not for use on CHARACTER expressions.
10978 Recursive descent on expr while making corresponding tree nodes and
10979 attaching type info and such. */
10982 ffecom_expr_rw (tree type, ffebld expr)
10984 assert (expr != NULL);
10985 /* Different target types not yet supported. */
10986 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
10988 return stabilize_reference (ffecom_expr (expr));
10991 /* Transform expr for use as into write tree and stabilize the
10992 reference. Not for use on CHARACTER expressions.
10994 Recursive descent on expr while making corresponding tree nodes and
10995 attaching type info and such. */
10998 ffecom_expr_w (tree type, ffebld expr)
11000 assert (expr != NULL);
11001 /* Different target types not yet supported. */
11002 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11004 return stabilize_reference (ffecom_expr (expr));
11007 /* Do global stuff. */
11010 ffecom_finish_compile ()
11012 assert (ffecom_outer_function_decl_ == NULL_TREE);
11013 assert (current_function_decl == NULL_TREE);
11015 ffeglobal_drive (ffecom_finish_global_);
11018 /* Public entry point for front end to access finish_decl. */
11021 ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11023 assert (!is_top_level);
11024 finish_decl (decl, init, FALSE);
11027 /* Finish a program unit. */
11030 ffecom_finish_progunit ()
11032 ffecom_end_compstmt ();
11034 ffecom_previous_function_decl_ = current_function_decl;
11035 ffecom_which_entrypoint_decl_ = NULL_TREE;
11037 finish_function (0);
11040 /* Wrapper for get_identifier. pattern is sprintf-like. */
11043 ffecom_get_invented_identifier (const char *pattern, ...)
11049 va_start (ap, pattern);
11050 if (vasprintf (&nam, pattern, ap) == 0)
11053 decl = get_identifier (nam);
11055 IDENTIFIER_INVENTED (decl) = 1;
11060 ffecom_gfrt_basictype (ffecomGfrt gfrt)
11062 assert (gfrt < FFECOM_gfrt);
11064 switch (ffecom_gfrt_type_[gfrt])
11066 case FFECOM_rttypeVOID_:
11067 case FFECOM_rttypeVOIDSTAR_:
11068 return FFEINFO_basictypeNONE;
11070 case FFECOM_rttypeFTNINT_:
11071 return FFEINFO_basictypeINTEGER;
11073 case FFECOM_rttypeINTEGER_:
11074 return FFEINFO_basictypeINTEGER;
11076 case FFECOM_rttypeLONGINT_:
11077 return FFEINFO_basictypeINTEGER;
11079 case FFECOM_rttypeLOGICAL_:
11080 return FFEINFO_basictypeLOGICAL;
11082 case FFECOM_rttypeREAL_F2C_:
11083 case FFECOM_rttypeREAL_GNU_:
11084 return FFEINFO_basictypeREAL;
11086 case FFECOM_rttypeCOMPLEX_F2C_:
11087 case FFECOM_rttypeCOMPLEX_GNU_:
11088 return FFEINFO_basictypeCOMPLEX;
11090 case FFECOM_rttypeDOUBLE_:
11091 case FFECOM_rttypeDOUBLEREAL_:
11092 return FFEINFO_basictypeREAL;
11094 case FFECOM_rttypeDBLCMPLX_F2C_:
11095 case FFECOM_rttypeDBLCMPLX_GNU_:
11096 return FFEINFO_basictypeCOMPLEX;
11098 case FFECOM_rttypeCHARACTER_:
11099 return FFEINFO_basictypeCHARACTER;
11102 return FFEINFO_basictypeANY;
11107 ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11109 assert (gfrt < FFECOM_gfrt);
11111 switch (ffecom_gfrt_type_[gfrt])
11113 case FFECOM_rttypeVOID_:
11114 case FFECOM_rttypeVOIDSTAR_:
11115 return FFEINFO_kindtypeNONE;
11117 case FFECOM_rttypeFTNINT_:
11118 return FFEINFO_kindtypeINTEGER1;
11120 case FFECOM_rttypeINTEGER_:
11121 return FFEINFO_kindtypeINTEGER1;
11123 case FFECOM_rttypeLONGINT_:
11124 return FFEINFO_kindtypeINTEGER4;
11126 case FFECOM_rttypeLOGICAL_:
11127 return FFEINFO_kindtypeLOGICAL1;
11129 case FFECOM_rttypeREAL_F2C_:
11130 case FFECOM_rttypeREAL_GNU_:
11131 return FFEINFO_kindtypeREAL1;
11133 case FFECOM_rttypeCOMPLEX_F2C_:
11134 case FFECOM_rttypeCOMPLEX_GNU_:
11135 return FFEINFO_kindtypeREAL1;
11137 case FFECOM_rttypeDOUBLE_:
11138 case FFECOM_rttypeDOUBLEREAL_:
11139 return FFEINFO_kindtypeREAL2;
11141 case FFECOM_rttypeDBLCMPLX_F2C_:
11142 case FFECOM_rttypeDBLCMPLX_GNU_:
11143 return FFEINFO_kindtypeREAL2;
11145 case FFECOM_rttypeCHARACTER_:
11146 return FFEINFO_kindtypeCHARACTER1;
11149 return FFEINFO_kindtypeANY;
11163 tree double_ftype_double;
11164 tree float_ftype_float;
11165 tree ldouble_ftype_ldouble;
11166 tree ffecom_tree_ptr_to_fun_type_void;
11168 /* This block of code comes from the now-obsolete cktyps.c. It checks
11169 whether the compiler environment is buggy in known ways, some of which
11170 would, if not explicitly checked here, result in subtle bugs in g77. */
11172 if (ffe_is_do_internal_checks ())
11174 static const char names[][12]
11176 {"bar", "bletch", "foo", "foobar"};
11181 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
11182 (int (*)(const void *, const void *)) strcmp);
11183 if (name != &names[0][2])
11185 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11190 ul = strtoul ("123456789", NULL, 10);
11191 if (ul != 123456789L)
11193 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11194 in proj.h" == NULL);
11198 fl = atof ("56.789");
11199 if ((fl < 56.788) || (fl > 56.79))
11201 assert ("atof not type double, fix your #include <stdio.h>"
11207 ffecom_outer_function_decl_ = NULL_TREE;
11208 current_function_decl = NULL_TREE;
11209 named_labels = NULL_TREE;
11210 current_binding_level = NULL_BINDING_LEVEL;
11211 free_binding_level = NULL_BINDING_LEVEL;
11212 /* Make the binding_level structure for global names. */
11214 global_binding_level = current_binding_level;
11215 current_binding_level->prep_state = 2;
11217 build_common_tree_nodes (1);
11219 /* Define `int' and `char' first so that dbx will output them first. */
11220 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11221 integer_type_node));
11222 /* CHARACTER*1 is unsigned in ICHAR contexts. */
11223 char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
11224 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11226 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11227 long_integer_type_node));
11228 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11229 unsigned_type_node));
11230 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11231 long_unsigned_type_node));
11232 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11233 long_long_integer_type_node));
11234 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11235 long_long_unsigned_type_node));
11236 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11237 short_integer_type_node));
11238 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11239 short_unsigned_type_node));
11241 /* Set the sizetype before we make other types. This *should* be the
11242 first type we create. */
11245 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
11246 ffecom_typesize_pointer_
11247 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype)) / BITS_PER_UNIT;
11249 build_common_tree_nodes_2 (0);
11251 /* Define both `signed char' and `unsigned char'. */
11252 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11253 signed_char_type_node));
11255 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11256 unsigned_char_type_node));
11258 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11260 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11261 double_type_node));
11262 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11263 long_double_type_node));
11265 /* For now, override what build_common_tree_nodes has done. */
11266 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
11267 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11268 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11269 complex_long_double_type_node
11270 = ffecom_make_complex_type_ (long_double_type_node);
11272 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11273 complex_integer_type_node));
11274 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11275 complex_float_type_node));
11276 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11277 complex_double_type_node));
11278 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11279 complex_long_double_type_node));
11281 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11283 /* We are not going to have real types in C with less than byte alignment,
11284 so we might as well not have any types that claim to have it. */
11285 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
11286 TYPE_USER_ALIGN (void_type_node) = 0;
11288 string_type_node = build_pointer_type (char_type_node);
11290 ffecom_tree_fun_type_void
11291 = build_function_type (void_type_node, NULL_TREE);
11293 ffecom_tree_ptr_to_fun_type_void
11294 = build_pointer_type (ffecom_tree_fun_type_void);
11296 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
11299 = build_function_type (float_type_node,
11300 tree_cons (NULL_TREE, float_type_node, endlink));
11302 double_ftype_double
11303 = build_function_type (double_type_node,
11304 tree_cons (NULL_TREE, double_type_node, endlink));
11306 ldouble_ftype_ldouble
11307 = build_function_type (long_double_type_node,
11308 tree_cons (NULL_TREE, long_double_type_node,
11311 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11312 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11314 ffecom_tree_type[i][j] = NULL_TREE;
11315 ffecom_tree_fun_type[i][j] = NULL_TREE;
11316 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11317 ffecom_f2c_typecode_[i][j] = -1;
11320 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11321 to size FLOAT_TYPE_SIZE because they have to be the same size as
11322 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11323 Compiler options and other such stuff that change the ways these
11324 types are set should not affect this particular setup. */
11326 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11327 = t = make_signed_type (FLOAT_TYPE_SIZE);
11328 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11330 type = ffetype_new ();
11332 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11334 ffetype_set_ams (type,
11335 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11336 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11337 ffetype_set_star (base_type,
11338 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11340 ffetype_set_kind (base_type, 1, type);
11341 ffecom_typesize_integer1_ = ffetype_size (type);
11342 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
11344 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11345 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11346 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11349 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11350 = t = make_signed_type (CHAR_TYPE_SIZE);
11351 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11353 type = ffetype_new ();
11354 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11356 ffetype_set_ams (type,
11357 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11358 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11359 ffetype_set_star (base_type,
11360 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11362 ffetype_set_kind (base_type, 3, type);
11363 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
11365 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11366 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11367 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11370 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11371 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11372 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11374 type = ffetype_new ();
11375 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11377 ffetype_set_ams (type,
11378 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11379 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11380 ffetype_set_star (base_type,
11381 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11383 ffetype_set_kind (base_type, 6, type);
11384 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
11386 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11387 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11388 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11391 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11392 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11393 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11395 type = ffetype_new ();
11396 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11398 ffetype_set_ams (type,
11399 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11400 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11401 ffetype_set_star (base_type,
11402 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11404 ffetype_set_kind (base_type, 2, type);
11405 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
11407 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11408 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11409 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11413 if (ffe_is_do_internal_checks ()
11414 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11415 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11416 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11417 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
11419 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11424 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11425 = t = make_signed_type (FLOAT_TYPE_SIZE);
11426 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11428 type = ffetype_new ();
11430 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11432 ffetype_set_ams (type,
11433 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11434 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11435 ffetype_set_star (base_type,
11436 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11438 ffetype_set_kind (base_type, 1, type);
11439 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
11441 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11442 = t = make_signed_type (CHAR_TYPE_SIZE);
11443 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11445 type = ffetype_new ();
11446 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11448 ffetype_set_ams (type,
11449 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11450 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11451 ffetype_set_star (base_type,
11452 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11454 ffetype_set_kind (base_type, 3, type);
11455 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
11457 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11458 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11459 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11461 type = ffetype_new ();
11462 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11464 ffetype_set_ams (type,
11465 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11466 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11467 ffetype_set_star (base_type,
11468 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11470 ffetype_set_kind (base_type, 6, type);
11471 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
11473 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11474 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11475 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11477 type = ffetype_new ();
11478 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11480 ffetype_set_ams (type,
11481 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11482 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11483 ffetype_set_star (base_type,
11484 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11486 ffetype_set_kind (base_type, 2, type);
11487 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
11489 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11490 = t = make_node (REAL_TYPE);
11491 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11492 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11495 type = ffetype_new ();
11497 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11499 ffetype_set_ams (type,
11500 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11501 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11502 ffetype_set_star (base_type,
11503 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11505 ffetype_set_kind (base_type, 1, type);
11506 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11507 = FFETARGET_f2cTYREAL;
11508 assert (ffetype_size (type) == sizeof (ffetargetReal1));
11510 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11511 = t = make_node (REAL_TYPE);
11512 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11513 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11516 type = ffetype_new ();
11517 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11519 ffetype_set_ams (type,
11520 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11521 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11522 ffetype_set_star (base_type,
11523 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11525 ffetype_set_kind (base_type, 2, type);
11526 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11527 = FFETARGET_f2cTYDREAL;
11528 assert (ffetype_size (type) == sizeof (ffetargetReal2));
11530 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11531 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11532 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11534 type = ffetype_new ();
11536 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11538 ffetype_set_ams (type,
11539 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11540 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11541 ffetype_set_star (base_type,
11542 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11544 ffetype_set_kind (base_type, 1, type);
11545 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11546 = FFETARGET_f2cTYCOMPLEX;
11547 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
11549 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11550 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11551 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11553 type = ffetype_new ();
11554 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11556 ffetype_set_ams (type,
11557 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11558 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11559 ffetype_set_star (base_type,
11560 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11562 ffetype_set_kind (base_type, 2,
11564 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11565 = FFETARGET_f2cTYDCOMPLEX;
11566 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
11568 /* Make function and ptr-to-function types for non-CHARACTER types. */
11570 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11571 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11573 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11575 if (i == FFEINFO_basictypeINTEGER)
11577 /* Figure out the smallest INTEGER type that can hold
11578 a pointer on this machine. */
11579 if (GET_MODE_SIZE (TYPE_MODE (t))
11580 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11582 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11583 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11584 > GET_MODE_SIZE (TYPE_MODE (t))))
11585 ffecom_pointer_kind_ = j;
11588 else if (i == FFEINFO_basictypeCOMPLEX)
11589 t = void_type_node;
11590 /* For f2c compatibility, REAL functions are really
11591 implemented as DOUBLE PRECISION. */
11592 else if ((i == FFEINFO_basictypeREAL)
11593 && (j == FFEINFO_kindtypeREAL1))
11594 t = ffecom_tree_type
11595 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
11597 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11599 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11603 /* Set up pointer types. */
11605 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
11606 fatal_error ("no INTEGER type can hold a pointer on this configuration");
11607 else if (0 && ffe_is_do_internal_checks ())
11608 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11609 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11610 FFEINFO_kindtypeINTEGERDEFAULT),
11612 ffeinfo_type (FFEINFO_basictypeINTEGER,
11613 ffecom_pointer_kind_));
11615 if (ffe_is_ugly_assign ())
11616 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
11618 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11619 if (0 && ffe_is_do_internal_checks ())
11620 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
11622 ffecom_integer_type_node
11623 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11624 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11625 integer_zero_node);
11626 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11629 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11630 Turns out that by TYLONG, runtime/libI77/lio.h really means
11631 "whatever size an ftnint is". For consistency and sanity,
11632 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
11633 all are INTEGER, which we also make out of whatever back-end
11634 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
11635 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
11636 accommodate machines like the Alpha. Note that this suggests
11637 f2c and libf2c are missing a distinction perhaps needed on
11638 some machines between "int" and "long int". -- burley 0.5.5 950215 */
11640 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
11641 FFETARGET_f2cTYLONG);
11642 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
11643 FFETARGET_f2cTYSHORT);
11644 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
11645 FFETARGET_f2cTYINT1);
11646 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
11647 FFETARGET_f2cTYQUAD);
11648 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
11649 FFETARGET_f2cTYLOGICAL);
11650 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
11651 FFETARGET_f2cTYLOGICAL2);
11652 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
11653 FFETARGET_f2cTYLOGICAL1);
11654 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
11655 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
11656 FFETARGET_f2cTYQUAD);
11658 /* CHARACTER stuff is all special-cased, so it is not handled in the above
11659 loop. CHARACTER items are built as arrays of unsigned char. */
11661 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
11662 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
11663 type = ffetype_new ();
11665 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
11666 FFEINFO_kindtypeCHARACTER1,
11668 ffetype_set_ams (type,
11669 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11670 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11671 ffetype_set_kind (base_type, 1, type);
11672 assert (ffetype_size (type)
11673 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
11675 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
11676 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
11677 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
11678 [FFEINFO_kindtypeCHARACTER1]
11679 = ffecom_tree_ptr_to_fun_type_void;
11680 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
11681 = FFETARGET_f2cTYCHAR;
11683 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
11686 /* Make multi-return-value type and fields. */
11688 ffecom_multi_type_node_ = make_node (UNION_TYPE);
11692 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11693 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11697 if (ffecom_tree_type[i][j] == NULL_TREE)
11698 continue; /* Not supported. */
11699 sprintf (&name[0], "bt_%s_kt_%s",
11700 ffeinfo_basictype_string ((ffeinfoBasictype) i),
11701 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
11702 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
11703 get_identifier (name),
11704 ffecom_tree_type[i][j]);
11705 DECL_CONTEXT (ffecom_multi_fields_[i][j])
11706 = ffecom_multi_type_node_;
11707 DECL_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11708 DECL_USER_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11709 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
11710 field = ffecom_multi_fields_[i][j];
11713 TYPE_FIELDS (ffecom_multi_type_node_) = field;
11714 layout_type (ffecom_multi_type_node_);
11716 /* Subroutines usually return integer because they might have alternate
11719 ffecom_tree_subr_type
11720 = build_function_type (integer_type_node, NULL_TREE);
11721 ffecom_tree_ptr_to_subr_type
11722 = build_pointer_type (ffecom_tree_subr_type);
11723 ffecom_tree_blockdata_type
11724 = build_function_type (void_type_node, NULL_TREE);
11726 builtin_function ("__builtin_sqrtf", float_ftype_float,
11727 BUILT_IN_SQRTF, BUILT_IN_NORMAL, "sqrtf");
11728 builtin_function ("__builtin_sqrt", double_ftype_double,
11729 BUILT_IN_SQRT, BUILT_IN_NORMAL, "sqrt");
11730 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
11731 BUILT_IN_SQRTL, BUILT_IN_NORMAL, "sqrtl");
11732 builtin_function ("__builtin_sinf", float_ftype_float,
11733 BUILT_IN_SINF, BUILT_IN_NORMAL, "sinf");
11734 builtin_function ("__builtin_sin", double_ftype_double,
11735 BUILT_IN_SIN, BUILT_IN_NORMAL, "sin");
11736 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
11737 BUILT_IN_SINL, BUILT_IN_NORMAL, "sinl");
11738 builtin_function ("__builtin_cosf", float_ftype_float,
11739 BUILT_IN_COSF, BUILT_IN_NORMAL, "cosf");
11740 builtin_function ("__builtin_cos", double_ftype_double,
11741 BUILT_IN_COS, BUILT_IN_NORMAL, "cos");
11742 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
11743 BUILT_IN_COSL, BUILT_IN_NORMAL, "cosl");
11745 pedantic_lvalues = FALSE;
11747 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
11750 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
11753 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
11756 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
11757 FFECOM_f2cDOUBLEREAL,
11759 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
11762 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
11763 FFECOM_f2cDOUBLECOMPLEX,
11765 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
11768 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
11771 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
11774 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
11777 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
11781 ffecom_f2c_ftnlen_zero_node
11782 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
11784 ffecom_f2c_ftnlen_one_node
11785 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
11787 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
11788 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
11790 ffecom_f2c_ptr_to_ftnlen_type_node
11791 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
11793 ffecom_f2c_ptr_to_ftnint_type_node
11794 = build_pointer_type (ffecom_f2c_ftnint_type_node);
11796 ffecom_f2c_ptr_to_integer_type_node
11797 = build_pointer_type (ffecom_f2c_integer_type_node);
11799 ffecom_f2c_ptr_to_real_type_node
11800 = build_pointer_type (ffecom_f2c_real_type_node);
11802 ffecom_float_zero_ = build_real (float_type_node, dconst0);
11803 ffecom_double_zero_ = build_real (double_type_node, dconst0);
11805 REAL_VALUE_TYPE point_5;
11807 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
11808 ffecom_float_half_ = build_real (float_type_node, point_5);
11809 ffecom_double_half_ = build_real (double_type_node, point_5);
11812 /* Do "extern int xargc;". */
11814 ffecom_tree_xargc_ = build_decl (VAR_DECL,
11815 get_identifier ("f__xargc"),
11816 integer_type_node);
11817 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
11818 TREE_STATIC (ffecom_tree_xargc_) = 1;
11819 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
11820 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
11821 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
11823 #if 0 /* This is being fixed, and seems to be working now. */
11824 if ((FLOAT_TYPE_SIZE != 32)
11825 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
11827 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
11828 (int) FLOAT_TYPE_SIZE);
11829 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
11830 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
11831 warning ("properly unless they all are 32 bits wide");
11832 warning ("Please keep this in mind before you report bugs.");
11836 #if 0 /* Code in ste.c that would crash has been commented out. */
11837 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
11838 < TYPE_PRECISION (string_type_node))
11839 /* I/O will probably crash. */
11840 warning ("configuration: char * holds %d bits, but ftnlen only %d",
11841 TYPE_PRECISION (string_type_node),
11842 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
11845 #if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
11846 if (TYPE_PRECISION (ffecom_integer_type_node)
11847 < TYPE_PRECISION (string_type_node))
11848 /* ASSIGN 10 TO I will crash. */
11849 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
11850 ASSIGN statement might fail",
11851 TYPE_PRECISION (string_type_node),
11852 TYPE_PRECISION (ffecom_integer_type_node));
11856 /* ffecom_init_2 -- Initialize
11858 ffecom_init_2(); */
11863 assert (ffecom_outer_function_decl_ == NULL_TREE);
11864 assert (current_function_decl == NULL_TREE);
11865 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
11867 ffecom_master_arglist_ = NULL;
11869 ffecom_primary_entry_ = NULL;
11870 ffecom_is_altreturning_ = FALSE;
11871 ffecom_func_result_ = NULL_TREE;
11872 ffecom_multi_retval_ = NULL_TREE;
11875 /* ffecom_list_expr -- Transform list of exprs into gcc tree
11878 ffebld expr; // FFE opITEM list.
11879 tree = ffecom_list_expr(expr);
11881 List of actual args is transformed into corresponding gcc backend list. */
11884 ffecom_list_expr (ffebld expr)
11887 tree *plist = &list;
11888 tree trail = NULL_TREE; /* Append char length args here. */
11889 tree *ptrail = &trail;
11892 while (expr != NULL)
11894 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
11896 if (texpr == error_mark_node)
11897 return error_mark_node;
11899 *plist = build_tree_list (NULL_TREE, texpr);
11900 plist = &TREE_CHAIN (*plist);
11901 expr = ffebld_trail (expr);
11902 if (length != NULL_TREE)
11904 *ptrail = build_tree_list (NULL_TREE, length);
11905 ptrail = &TREE_CHAIN (*ptrail);
11914 /* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
11917 ffebld expr; // FFE opITEM list.
11918 tree = ffecom_list_ptr_to_expr(expr);
11920 List of actual args is transformed into corresponding gcc backend list for
11921 use in calling an external procedure (vs. a statement function). */
11924 ffecom_list_ptr_to_expr (ffebld expr)
11927 tree *plist = &list;
11928 tree trail = NULL_TREE; /* Append char length args here. */
11929 tree *ptrail = &trail;
11932 while (expr != NULL)
11934 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
11936 if (texpr == error_mark_node)
11937 return error_mark_node;
11939 *plist = build_tree_list (NULL_TREE, texpr);
11940 plist = &TREE_CHAIN (*plist);
11941 expr = ffebld_trail (expr);
11942 if (length != NULL_TREE)
11944 *ptrail = build_tree_list (NULL_TREE, length);
11945 ptrail = &TREE_CHAIN (*ptrail);
11954 /* Obtain gcc's LABEL_DECL tree for label. */
11957 ffecom_lookup_label (ffelab label)
11961 if (ffelab_hook (label) == NULL_TREE)
11963 char labelname[16];
11965 switch (ffelab_type (label))
11967 case FFELAB_typeLOOPEND:
11968 case FFELAB_typeNOTLOOP:
11969 case FFELAB_typeENDIF:
11970 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
11971 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
11973 DECL_CONTEXT (glabel) = current_function_decl;
11974 DECL_MODE (glabel) = VOIDmode;
11977 case FFELAB_typeFORMAT:
11978 glabel = build_decl (VAR_DECL,
11979 ffecom_get_invented_identifier
11980 ("__g77_format_%d", (int) ffelab_value (label)),
11981 build_type_variant (build_array_type
11985 TREE_CONSTANT (glabel) = 1;
11986 TREE_STATIC (glabel) = 1;
11987 DECL_CONTEXT (glabel) = current_function_decl;
11988 DECL_INITIAL (glabel) = NULL;
11989 make_decl_rtl (glabel, NULL);
11990 expand_decl (glabel);
11992 ffecom_save_tree_forever (glabel);
11996 case FFELAB_typeANY:
11997 glabel = error_mark_node;
12001 assert ("bad label type" == NULL);
12005 ffelab_set_hook (label, glabel);
12009 glabel = ffelab_hook (label);
12015 /* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12016 a single source specification (as in the fourth argument of MVBITS).
12017 If the type is NULL_TREE, the type of lhs is used to make the type of
12018 the MODIFY_EXPR. */
12021 ffecom_modify (tree newtype, tree lhs,
12024 if (lhs == error_mark_node || rhs == error_mark_node)
12025 return error_mark_node;
12027 if (newtype == NULL_TREE)
12028 newtype = TREE_TYPE (lhs);
12030 if (TREE_SIDE_EFFECTS (lhs))
12031 lhs = stabilize_reference (lhs);
12033 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12036 /* Register source file name. */
12039 ffecom_file (const char *name)
12041 ffecom_file_ (name);
12044 /* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
12047 ffecom_notify_init_storage(st);
12049 Gets called when all possible units in an aggregate storage area (a LOCAL
12050 with equivalences or a COMMON) have been initialized. The initialization
12051 info either is in ffestorag_init or, if that is NULL,
12052 ffestorag_accretion:
12054 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12055 even for an array if the array is one element in length!
12057 ffestorag_accretion will contain an opACCTER. It is much like an
12058 opARRTER except it has an ffebit object in it instead of just a size.
12059 The back end can use the info in the ffebit object, if it wants, to
12060 reduce the amount of actual initialization, but in any case it should
12061 kill the ffebit object when done. Also, set accretion to NULL but
12062 init to a non-NULL value.
12064 After performing initialization, DO NOT set init to NULL, because that'll
12065 tell the front end it is ok for more initialization to happen. Instead,
12066 set init to an opANY expression or some such thing that you can use to
12067 tell that you've already initialized the object.
12070 Support two-pass FFE. */
12073 ffecom_notify_init_storage (ffestorag st)
12075 ffebld init; /* The initialization expression. */
12077 if (ffestorag_init (st) == NULL)
12079 init = ffestorag_accretion (st);
12080 assert (init != NULL);
12081 ffestorag_set_accretion (st, NULL);
12082 ffestorag_set_accretes (st, 0);
12083 ffestorag_set_init (st, init);
12087 /* ffecom_notify_init_symbol -- A symbol is now fully init'ed
12090 ffecom_notify_init_symbol(s);
12092 Gets called when all possible units in a symbol (not placed in COMMON
12093 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12094 have been initialized. The initialization info either is in
12095 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
12097 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12098 even for an array if the array is one element in length!
12100 ffesymbol_accretion will contain an opACCTER. It is much like an
12101 opARRTER except it has an ffebit object in it instead of just a size.
12102 The back end can use the info in the ffebit object, if it wants, to
12103 reduce the amount of actual initialization, but in any case it should
12104 kill the ffebit object when done. Also, set accretion to NULL but
12105 init to a non-NULL value.
12107 After performing initialization, DO NOT set init to NULL, because that'll
12108 tell the front end it is ok for more initialization to happen. Instead,
12109 set init to an opANY expression or some such thing that you can use to
12110 tell that you've already initialized the object.
12113 Support two-pass FFE. */
12116 ffecom_notify_init_symbol (ffesymbol s)
12118 ffebld init; /* The initialization expression. */
12120 if (ffesymbol_storage (s) == NULL)
12121 return; /* Do nothing until COMMON/EQUIVALENCE
12122 possibilities checked. */
12124 if ((ffesymbol_init (s) == NULL)
12125 && ((init = ffesymbol_accretion (s)) != NULL))
12127 ffesymbol_set_accretion (s, NULL);
12128 ffesymbol_set_accretes (s, 0);
12129 ffesymbol_set_init (s, init);
12133 /* ffecom_notify_primary_entry -- Learn which is the primary entry point
12136 ffecom_notify_primary_entry(s);
12138 Gets called when implicit or explicit PROGRAM statement seen or when
12139 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12140 global symbol that serves as the entry point. */
12143 ffecom_notify_primary_entry (ffesymbol s)
12145 ffecom_primary_entry_ = s;
12146 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
12148 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12149 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12150 ffecom_primary_entry_is_proc_ = TRUE;
12152 ffecom_primary_entry_is_proc_ = FALSE;
12154 if (!ffe_is_silent ())
12156 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12157 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12159 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12162 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12167 for (list = ffesymbol_dummyargs (s);
12169 list = ffebld_trail (list))
12171 arg = ffebld_head (list);
12172 if (ffebld_op (arg) == FFEBLD_opSTAR)
12174 ffecom_is_altreturning_ = TRUE;
12182 ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12184 return ffecom_open_include_ (name, l, c);
12187 /* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
12190 ffebld expr; // FFE expression.
12191 tree = ffecom_ptr_to_expr(expr);
12193 Like ffecom_expr, but sticks address-of in front of most things. */
12196 ffecom_ptr_to_expr (ffebld expr)
12199 ffeinfoBasictype bt;
12200 ffeinfoKindtype kt;
12203 assert (expr != NULL);
12205 switch (ffebld_op (expr))
12207 case FFEBLD_opSYMTER:
12208 s = ffebld_symter (expr);
12209 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12213 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12214 assert (ix != FFECOM_gfrt);
12215 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12217 ffecom_make_gfrt_ (ix);
12218 item = ffecom_gfrt_[ix];
12223 item = ffesymbol_hook (s).decl_tree;
12224 if (item == NULL_TREE)
12226 s = ffecom_sym_transform_ (s);
12227 item = ffesymbol_hook (s).decl_tree;
12230 assert (item != NULL);
12231 if (item == error_mark_node)
12233 if (!ffesymbol_hook (s).addr)
12234 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12238 case FFEBLD_opARRAYREF:
12239 return ffecom_arrayref_ (NULL_TREE, expr, 1);
12241 case FFEBLD_opCONTER:
12243 bt = ffeinfo_basictype (ffebld_info (expr));
12244 kt = ffeinfo_kindtype (ffebld_info (expr));
12246 item = ffecom_constantunion (&ffebld_constant_union
12247 (ffebld_conter (expr)), bt, kt,
12248 ffecom_tree_type[bt][kt]);
12249 if (item == error_mark_node)
12250 return error_mark_node;
12251 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12256 return error_mark_node;
12259 bt = ffeinfo_basictype (ffebld_info (expr));
12260 kt = ffeinfo_kindtype (ffebld_info (expr));
12262 item = ffecom_expr (expr);
12263 if (item == error_mark_node)
12264 return error_mark_node;
12266 /* The back end currently optimizes a bit too zealously for us, in that
12267 we fail JCB001 if the following block of code is omitted. It checks
12268 to see if the transformed expression is a symbol or array reference,
12269 and encloses it in a SAVE_EXPR if that is the case. */
12272 if ((TREE_CODE (item) == VAR_DECL)
12273 || (TREE_CODE (item) == PARM_DECL)
12274 || (TREE_CODE (item) == RESULT_DECL)
12275 || (TREE_CODE (item) == INDIRECT_REF)
12276 || (TREE_CODE (item) == ARRAY_REF)
12277 || (TREE_CODE (item) == COMPONENT_REF)
12279 || (TREE_CODE (item) == OFFSET_REF)
12281 || (TREE_CODE (item) == BUFFER_REF)
12282 || (TREE_CODE (item) == REALPART_EXPR)
12283 || (TREE_CODE (item) == IMAGPART_EXPR))
12285 item = ffecom_save_tree (item);
12288 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12293 assert ("fall-through error" == NULL);
12294 return error_mark_node;
12297 /* Obtain a temp var with given data type.
12299 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12300 or >= 0 for a CHARACTER type.
12302 elements is -1 for a scalar or > 0 for an array of type. */
12305 ffecom_make_tempvar (const char *commentary, tree type,
12306 ffetargetCharacterSize size, int elements)
12309 static int mynumber;
12311 assert (current_binding_level->prep_state < 2);
12313 if (type == error_mark_node)
12314 return error_mark_node;
12316 if (size != FFETARGET_charactersizeNONE)
12317 type = build_array_type (type,
12318 build_range_type (ffecom_f2c_ftnlen_type_node,
12319 ffecom_f2c_ftnlen_one_node,
12320 build_int_2 (size, 0)));
12321 if (elements != -1)
12322 type = build_array_type (type,
12323 build_range_type (integer_type_node,
12325 build_int_2 (elements - 1,
12327 t = build_decl (VAR_DECL,
12328 ffecom_get_invented_identifier ("__g77_%s_%d",
12333 t = start_decl (t, FALSE);
12334 finish_decl (t, NULL_TREE, FALSE);
12339 /* Prepare argument pointer to expression.
12341 Like ffecom_prepare_expr, except for expressions to be evaluated
12342 via ffecom_arg_ptr_to_expr. */
12345 ffecom_prepare_arg_ptr_to_expr (ffebld expr)
12347 /* ~~For now, it seems to be the same thing. */
12348 ffecom_prepare_expr (expr);
12352 /* End of preparations. */
12355 ffecom_prepare_end (void)
12357 int prep_state = current_binding_level->prep_state;
12359 assert (prep_state < 2);
12360 current_binding_level->prep_state = 2;
12362 return (prep_state == 1) ? TRUE : FALSE;
12365 /* Prepare expression.
12367 This is called before any code is generated for the current block.
12368 It scans the expression, declares any temporaries that might be needed
12369 during evaluation of the expression, and stores those temporaries in
12370 the appropriate "hook" fields of the expression. `dest', if not NULL,
12371 specifies the destination that ffecom_expr_ will see, in case that
12372 helps avoid generating unused temporaries.
12374 ~~Improve to avoid allocating unused temporaries by taking `dest'
12375 into account vis-a-vis aliasing requirements of complex/character
12379 ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
12381 ffeinfoBasictype bt;
12382 ffeinfoKindtype kt;
12383 ffetargetCharacterSize sz;
12384 tree tempvar = NULL_TREE;
12386 assert (current_binding_level->prep_state < 2);
12391 bt = ffeinfo_basictype (ffebld_info (expr));
12392 kt = ffeinfo_kindtype (ffebld_info (expr));
12393 sz = ffeinfo_size (ffebld_info (expr));
12395 /* Generate whatever temporaries are needed to represent the result
12396 of the expression. */
12398 if (bt == FFEINFO_basictypeCHARACTER)
12400 while (ffebld_op (expr) == FFEBLD_opPAREN)
12401 expr = ffebld_left (expr);
12404 switch (ffebld_op (expr))
12407 /* Don't make temps for SYMTER, CONTER, etc. */
12408 if (ffebld_arity (expr) == 0)
12413 case FFEINFO_basictypeCOMPLEX:
12414 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12418 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12421 s = ffebld_symter (ffebld_left (expr));
12422 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
12423 || (ffesymbol_where (s) != FFEINFO_whereINTRINSIC
12424 && ! ffesymbol_is_f2c (s))
12425 || (ffesymbol_where (s) == FFEINFO_whereINTRINSIC
12426 && ! ffe_is_f2c_library ()))
12429 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12431 /* Requires special treatment. There's no POW_CC function
12432 in libg2c, so POW_ZZ is used, which means we always
12433 need a double-complex temp, not a single-complex. */
12434 kt = FFEINFO_kindtypeREAL2;
12436 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12437 /* The other ops don't need temps for complex operands. */
12440 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12441 REAL(C). See 19990325-0.f, routine `check', for cases. */
12442 tempvar = ffecom_make_tempvar ("complex",
12444 [FFEINFO_basictypeCOMPLEX][kt],
12445 FFETARGET_charactersizeNONE,
12449 case FFEINFO_basictypeCHARACTER:
12450 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12453 if (sz == FFETARGET_charactersizeNONE)
12454 /* ~~Kludge alert! This should someday be fixed. */
12457 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
12466 case FFEBLD_opPOWER:
12469 tree rtmp, ltmp, result;
12471 ltype = ffecom_type_expr (ffebld_left (expr));
12472 rtype = ffecom_type_expr (ffebld_right (expr));
12474 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
12475 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12476 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12478 tempvar = make_tree_vec (3);
12479 TREE_VEC_ELT (tempvar, 0) = rtmp;
12480 TREE_VEC_ELT (tempvar, 1) = ltmp;
12481 TREE_VEC_ELT (tempvar, 2) = result;
12486 case FFEBLD_opCONCATENATE:
12488 /* This gets special handling, because only one set of temps
12489 is needed for a tree of these -- the tree is treated as
12490 a flattened list of concatenations when generating code. */
12492 ffecomConcatList_ catlist;
12493 tree ltmp, itmp, result;
12497 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12498 count = ffecom_concat_list_count_ (catlist);
12503 = ffecom_make_tempvar ("concat_len",
12504 ffecom_f2c_ftnlen_type_node,
12505 FFETARGET_charactersizeNONE, count);
12507 = ffecom_make_tempvar ("concat_item",
12508 ffecom_f2c_address_type_node,
12509 FFETARGET_charactersizeNONE, count);
12511 = ffecom_make_tempvar ("concat_res",
12513 ffecom_concat_list_maxlen_ (catlist),
12516 tempvar = make_tree_vec (3);
12517 TREE_VEC_ELT (tempvar, 0) = ltmp;
12518 TREE_VEC_ELT (tempvar, 1) = itmp;
12519 TREE_VEC_ELT (tempvar, 2) = result;
12522 for (i = 0; i < count; ++i)
12523 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
12526 ffecom_concat_list_kill_ (catlist);
12530 ffebld_nonter_set_hook (expr, tempvar);
12531 current_binding_level->prep_state = 1;
12536 case FFEBLD_opCONVERT:
12537 if (bt == FFEINFO_basictypeCHARACTER
12538 && ((ffebld_size_known (ffebld_left (expr))
12539 == FFETARGET_charactersizeNONE)
12540 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
12541 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
12547 ffebld_nonter_set_hook (expr, tempvar);
12548 current_binding_level->prep_state = 1;
12551 /* Prepare subexpressions for this expr. */
12553 switch (ffebld_op (expr))
12555 case FFEBLD_opPERCENT_LOC:
12556 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
12559 case FFEBLD_opPERCENT_VAL:
12560 case FFEBLD_opPERCENT_REF:
12561 ffecom_prepare_expr (ffebld_left (expr));
12564 case FFEBLD_opPERCENT_DESCR:
12565 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
12568 case FFEBLD_opITEM:
12574 item = ffebld_trail (item))
12575 if (ffebld_head (item) != NULL)
12576 ffecom_prepare_expr (ffebld_head (item));
12581 /* Need to handle character conversion specially. */
12582 switch (ffebld_arity (expr))
12585 ffecom_prepare_expr (ffebld_left (expr));
12586 ffecom_prepare_expr (ffebld_right (expr));
12590 ffecom_prepare_expr (ffebld_left (expr));
12601 /* Prepare expression for reading and writing.
12603 Like ffecom_prepare_expr, except for expressions to be evaluated
12604 via ffecom_expr_rw. */
12607 ffecom_prepare_expr_rw (tree type, ffebld expr)
12609 /* This is all we support for now. */
12610 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
12612 /* ~~For now, it seems to be the same thing. */
12613 ffecom_prepare_expr (expr);
12617 /* Prepare expression for writing.
12619 Like ffecom_prepare_expr, except for expressions to be evaluated
12620 via ffecom_expr_w. */
12623 ffecom_prepare_expr_w (tree type, ffebld expr)
12625 /* This is all we support for now. */
12626 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
12628 /* ~~For now, it seems to be the same thing. */
12629 ffecom_prepare_expr (expr);
12633 /* Prepare expression for returning.
12635 Like ffecom_prepare_expr, except for expressions to be evaluated
12636 via ffecom_return_expr. */
12639 ffecom_prepare_return_expr (ffebld expr)
12641 assert (current_binding_level->prep_state < 2);
12643 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
12644 && ffecom_is_altreturning_
12646 ffecom_prepare_expr (expr);
12649 /* Prepare pointer to expression.
12651 Like ffecom_prepare_expr, except for expressions to be evaluated
12652 via ffecom_ptr_to_expr. */
12655 ffecom_prepare_ptr_to_expr (ffebld expr)
12657 /* ~~For now, it seems to be the same thing. */
12658 ffecom_prepare_expr (expr);
12662 /* Transform expression into constant pointer-to-expression tree.
12664 If the expression can be transformed into a pointer-to-expression tree
12665 that is constant, that is done, and the tree returned. Else NULL_TREE
12668 That way, a caller can attempt to provide compile-time initialization
12669 of a variable and, if that fails, *then* choose to start a new block
12670 and resort to using temporaries, as appropriate. */
12673 ffecom_ptr_to_const_expr (ffebld expr)
12676 return integer_zero_node;
12678 if (ffebld_op (expr) == FFEBLD_opANY)
12679 return error_mark_node;
12681 if (ffebld_arity (expr) == 0
12682 && (ffebld_op (expr) != FFEBLD_opSYMTER
12683 || ffebld_where (expr) == FFEINFO_whereCOMMON
12684 || ffebld_where (expr) == FFEINFO_whereGLOBAL
12685 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
12689 t = ffecom_ptr_to_expr (expr);
12690 assert (TREE_CONSTANT (t));
12697 /* ffecom_return_expr -- Returns return-value expr given alt return expr
12699 tree rtn; // NULL_TREE means use expand_null_return()
12700 ffebld expr; // NULL if no alt return expr to RETURN stmt
12701 rtn = ffecom_return_expr(expr);
12703 Based on the program unit type and other info (like return function
12704 type, return master function type when alternate ENTRY points,
12705 whether subroutine has any alternate RETURN points, etc), returns the
12706 appropriate expression to be returned to the caller, or NULL_TREE
12707 meaning no return value or the caller expects it to be returned somewhere
12708 else (which is handled by other parts of this module). */
12711 ffecom_return_expr (ffebld expr)
12715 switch (ffecom_primary_entry_kind_)
12717 case FFEINFO_kindPROGRAM:
12718 case FFEINFO_kindBLOCKDATA:
12722 case FFEINFO_kindSUBROUTINE:
12723 if (!ffecom_is_altreturning_)
12724 rtn = NULL_TREE; /* No alt returns, never an expr. */
12725 else if (expr == NULL)
12726 rtn = integer_zero_node;
12728 rtn = ffecom_expr (expr);
12731 case FFEINFO_kindFUNCTION:
12732 if ((ffecom_multi_retval_ != NULL_TREE)
12733 || (ffesymbol_basictype (ffecom_primary_entry_)
12734 == FFEINFO_basictypeCHARACTER)
12735 || ((ffesymbol_basictype (ffecom_primary_entry_)
12736 == FFEINFO_basictypeCOMPLEX)
12737 && (ffecom_num_entrypoints_ == 0)
12738 && ffesymbol_is_f2c (ffecom_primary_entry_)))
12739 { /* Value is returned by direct assignment
12740 into (implicit) dummy. */
12744 rtn = ffecom_func_result_;
12746 /* Spurious error if RETURN happens before first reference! So elide
12747 this code. In particular, for debugging registry, rtn should always
12748 be non-null after all, but TREE_USED won't be set until we encounter
12749 a reference in the code. Perfectly okay (but weird) code that,
12750 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
12751 this diagnostic for no reason. Have people use -O -Wuninitialized
12752 and leave it to the back end to find obviously weird cases. */
12754 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
12755 situation; if the return value has never been referenced, it won't
12756 have a tree under 2pass mode. */
12757 if ((rtn == NULL_TREE)
12758 || !TREE_USED (rtn))
12760 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
12761 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
12762 ffesymbol_where_column (ffecom_primary_entry_));
12763 ffebad_string (ffesymbol_text (ffesymbol_funcresult
12764 (ffecom_primary_entry_)));
12771 assert ("bad unit kind" == NULL);
12772 case FFEINFO_kindANY:
12773 rtn = error_mark_node;
12780 /* Do save_expr only if tree is not error_mark_node. */
12783 ffecom_save_tree (tree t)
12785 return save_expr (t);
12788 /* Start a compound statement (block). */
12791 ffecom_start_compstmt (void)
12793 bison_rule_pushlevel_ ();
12796 /* Public entry point for front end to access start_decl. */
12799 ffecom_start_decl (tree decl, bool is_initialized)
12801 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
12802 return start_decl (decl, FALSE);
12805 /* ffecom_sym_commit -- Symbol's state being committed to reality
12808 ffecom_sym_commit(s);
12810 Does whatever the backend needs when a symbol is committed after having
12811 been backtrackable for a period of time. */
12814 ffecom_sym_commit (ffesymbol s UNUSED)
12816 assert (!ffesymbol_retractable ());
12819 /* ffecom_sym_end_transition -- Perform end transition on all symbols
12821 ffecom_sym_end_transition();
12823 Does backend-specific stuff and also calls ffest_sym_end_transition
12824 to do the necessary FFE stuff.
12826 Backtracking is never enabled when this fn is called, so don't worry
12830 ffecom_sym_end_transition (ffesymbol s)
12834 assert (!ffesymbol_retractable ());
12836 s = ffest_sym_end_transition (s);
12838 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
12839 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
12841 ffecom_list_blockdata_
12842 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12843 FFEINTRIN_specNONE,
12844 FFEINTRIN_impNONE),
12845 ffecom_list_blockdata_);
12848 /* This is where we finally notice that a symbol has partial initialization
12849 and finalize it. */
12851 if (ffesymbol_accretion (s) != NULL)
12853 assert (ffesymbol_init (s) == NULL);
12854 ffecom_notify_init_symbol (s);
12856 else if (((st = ffesymbol_storage (s)) != NULL)
12857 && ((st = ffestorag_parent (st)) != NULL)
12858 && (ffestorag_accretion (st) != NULL))
12860 assert (ffestorag_init (st) == NULL);
12861 ffecom_notify_init_storage (st);
12864 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
12865 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
12866 && (ffesymbol_storage (s) != NULL))
12868 ffecom_list_common_
12869 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12870 FFEINTRIN_specNONE,
12871 FFEINTRIN_impNONE),
12872 ffecom_list_common_);
12878 /* ffecom_sym_exec_transition -- Perform exec transition on all symbols
12880 ffecom_sym_exec_transition();
12882 Does backend-specific stuff and also calls ffest_sym_exec_transition
12883 to do the necessary FFE stuff.
12885 See the long-winded description in ffecom_sym_learned for info
12886 on handling the situation where backtracking is inhibited. */
12889 ffecom_sym_exec_transition (ffesymbol s)
12891 s = ffest_sym_exec_transition (s);
12896 /* ffecom_sym_learned -- Initial or more info gained on symbol after exec
12899 s = ffecom_sym_learned(s);
12901 Called when a new symbol is seen after the exec transition or when more
12902 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
12903 it arrives here is that all its latest info is updated already, so its
12904 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
12905 field filled in if its gone through here or exec_transition first, and
12908 The backend probably wants to check ffesymbol_retractable() to see if
12909 backtracking is in effect. If so, the FFE's changes to the symbol may
12910 be retracted (undone) or committed (ratified), at which time the
12911 appropriate ffecom_sym_retract or _commit function will be called
12914 If the backend has its own backtracking mechanism, great, use it so that
12915 committal is a simple operation. Though it doesn't make much difference,
12916 I suppose: the reason for tentative symbol evolution in the FFE is to
12917 enable error detection in weird incorrect statements early and to disable
12918 incorrect error detection on a correct statement. The backend is not
12919 likely to introduce any information that'll get involved in these
12920 considerations, so it is probably just fine that the implementation
12921 model for this fn and for _exec_transition is to not do anything
12922 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
12923 and instead wait until ffecom_sym_commit is called (which it never
12924 will be as long as we're using ambiguity-detecting statement analysis in
12925 the FFE, which we are initially to shake out the code, but don't depend
12926 on this), otherwise go ahead and do whatever is needed.
12928 In essence, then, when this fn and _exec_transition get called while
12929 backtracking is enabled, a general mechanism would be to flag which (or
12930 both) of these were called (and in what order? neat question as to what
12931 might happen that I'm too lame to think through right now) and then when
12932 _commit is called reproduce the original calling sequence, if any, for
12933 the two fns (at which point backtracking will, of course, be disabled). */
12936 ffecom_sym_learned (ffesymbol s)
12938 ffestorag_exec_layout (s);
12943 /* ffecom_sym_retract -- Symbol's state being retracted from reality
12946 ffecom_sym_retract(s);
12948 Does whatever the backend needs when a symbol is retracted after having
12949 been backtrackable for a period of time. */
12952 ffecom_sym_retract (ffesymbol s UNUSED)
12954 assert (!ffesymbol_retractable ());
12956 #if 0 /* GCC doesn't commit any backtrackable sins,
12957 so nothing needed here. */
12958 switch (ffesymbol_hook (s).state)
12960 case 0: /* nothing happened yet. */
12963 case 1: /* exec transition happened. */
12966 case 2: /* learned happened. */
12969 case 3: /* learned then exec. */
12972 case 4: /* exec then learned. */
12976 assert ("bad hook state" == NULL);
12982 /* Create temporary gcc label. */
12985 ffecom_temp_label ()
12988 static int mynumber = 0;
12990 glabel = build_decl (LABEL_DECL,
12991 ffecom_get_invented_identifier ("__g77_label_%d",
12994 DECL_CONTEXT (glabel) = current_function_decl;
12995 DECL_MODE (glabel) = VOIDmode;
13000 /* Return an expression that is usable as an arg in a conditional context
13001 (IF, DO WHILE, .NOT., and so on).
13003 Use the one provided for the back end as of >2.6.0. */
13006 ffecom_truth_value (tree expr)
13008 return truthvalue_conversion (expr);
13011 /* Return the inversion of a truth value (the inversion of what
13012 ffecom_truth_value builds).
13014 Apparently invert_truthvalue, which is properly in the back end, is
13015 enough for now, so just use it. */
13018 ffecom_truth_value_invert (tree expr)
13020 return invert_truthvalue (ffecom_truth_value (expr));
13023 /* Return the tree that is the type of the expression, as would be
13024 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13025 transforming the expression, generating temporaries, etc. */
13028 ffecom_type_expr (ffebld expr)
13030 ffeinfoBasictype bt;
13031 ffeinfoKindtype kt;
13034 assert (expr != NULL);
13036 bt = ffeinfo_basictype (ffebld_info (expr));
13037 kt = ffeinfo_kindtype (ffebld_info (expr));
13038 tree_type = ffecom_tree_type[bt][kt];
13040 switch (ffebld_op (expr))
13042 case FFEBLD_opCONTER:
13043 case FFEBLD_opSYMTER:
13044 case FFEBLD_opARRAYREF:
13045 case FFEBLD_opUPLUS:
13046 case FFEBLD_opPAREN:
13047 case FFEBLD_opUMINUS:
13049 case FFEBLD_opSUBTRACT:
13050 case FFEBLD_opMULTIPLY:
13051 case FFEBLD_opDIVIDE:
13052 case FFEBLD_opPOWER:
13054 case FFEBLD_opFUNCREF:
13055 case FFEBLD_opSUBRREF:
13059 case FFEBLD_opNEQV:
13061 case FFEBLD_opCONVERT:
13068 case FFEBLD_opPERCENT_LOC:
13071 case FFEBLD_opACCTER:
13072 case FFEBLD_opARRTER:
13073 case FFEBLD_opITEM:
13074 case FFEBLD_opSTAR:
13075 case FFEBLD_opBOUNDS:
13076 case FFEBLD_opREPEAT:
13077 case FFEBLD_opLABTER:
13078 case FFEBLD_opLABTOK:
13079 case FFEBLD_opIMPDO:
13080 case FFEBLD_opCONCATENATE:
13081 case FFEBLD_opSUBSTR:
13083 assert ("bad op for ffecom_type_expr" == NULL);
13084 /* Fall through. */
13086 return error_mark_node;
13090 /* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13092 If the PARM_DECL already exists, return it, else create it. It's an
13093 integer_type_node argument for the master function that implements a
13094 subroutine or function with more than one entrypoint and is bound at
13095 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13096 first ENTRY statement, and so on). */
13099 ffecom_which_entrypoint_decl ()
13101 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13103 return ffecom_which_entrypoint_decl_;
13106 /* The following sections consists of private and public functions
13107 that have the same names and perform roughly the same functions
13108 as counterparts in the C front end. Changes in the C front end
13109 might affect how things should be done here. Only functions
13110 needed by the back end should be public here; the rest should
13111 be private (static in the C sense). Functions needed by other
13112 g77 front-end modules should be accessed by them via public
13113 ffecom_* names, which should themselves call private versions
13114 in this section so the private versions are easy to recognize
13115 when upgrading to a new gcc and finding interesting changes
13118 Functions named after rule "foo:" in c-parse.y are named
13119 "bison_rule_foo_" so they are easy to find. */
13122 bison_rule_pushlevel_ ()
13124 emit_line_note (input_filename, lineno);
13126 clear_last_expr ();
13127 expand_start_bindings (0);
13131 bison_rule_compstmt_ ()
13134 int keep = kept_level_p ();
13136 /* Make the temps go away. */
13138 current_binding_level->names = NULL_TREE;
13140 emit_line_note (input_filename, lineno);
13141 expand_end_bindings (getdecls (), keep, 0);
13142 t = poplevel (keep, 1, 0);
13147 /* Return a definition for a builtin function named NAME and whose data type
13148 is TYPE. TYPE should be a function type with argument types.
13149 FUNCTION_CODE tells later passes how to compile calls to this function.
13150 See tree.h for its possible values.
13152 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13153 the name to be called if we can't opencode the function. */
13156 builtin_function (const char *name, tree type, int function_code,
13157 enum built_in_class class,
13158 const char *library_name)
13160 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13161 DECL_EXTERNAL (decl) = 1;
13162 TREE_PUBLIC (decl) = 1;
13164 SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
13165 make_decl_rtl (decl, NULL);
13167 DECL_BUILT_IN_CLASS (decl) = class;
13168 DECL_FUNCTION_CODE (decl) = function_code;
13173 /* Handle when a new declaration NEWDECL
13174 has the same name as an old one OLDDECL
13175 in the same binding contour.
13176 Prints an error message if appropriate.
13178 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13179 Otherwise, return 0. */
13182 duplicate_decls (tree newdecl, tree olddecl)
13184 int types_match = 1;
13185 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13186 && DECL_INITIAL (newdecl) != 0);
13187 tree oldtype = TREE_TYPE (olddecl);
13188 tree newtype = TREE_TYPE (newdecl);
13190 if (olddecl == newdecl)
13193 if (TREE_CODE (newtype) == ERROR_MARK
13194 || TREE_CODE (oldtype) == ERROR_MARK)
13197 /* New decl is completely inconsistent with the old one =>
13198 tell caller to replace the old one.
13199 This is always an error except in the case of shadowing a builtin. */
13200 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13203 /* For real parm decl following a forward decl,
13204 return 1 so old decl will be reused. */
13205 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13206 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13209 /* The new declaration is the same kind of object as the old one.
13210 The declarations may partially match. Print warnings if they don't
13211 match enough. Ultimately, copy most of the information from the new
13212 decl to the old one, and keep using the old one. */
13214 if (TREE_CODE (olddecl) == FUNCTION_DECL
13215 && DECL_BUILT_IN (olddecl))
13217 /* A function declaration for a built-in function. */
13218 if (!TREE_PUBLIC (newdecl))
13220 else if (!types_match)
13222 /* Accept the return type of the new declaration if same modes. */
13223 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13224 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
13226 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13228 /* Function types may be shared, so we can't just modify
13229 the return type of olddecl's function type. */
13231 = build_function_type (newreturntype,
13232 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
13236 TREE_TYPE (olddecl) = newtype;
13242 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13243 && DECL_SOURCE_LINE (olddecl) == 0)
13245 /* A function declaration for a predeclared function
13246 that isn't actually built in. */
13247 if (!TREE_PUBLIC (newdecl))
13249 else if (!types_match)
13251 /* If the types don't match, preserve volatility indication.
13252 Later on, we will discard everything else about the
13253 default declaration. */
13254 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13258 /* Copy all the DECL_... slots specified in the new decl
13259 except for any that we copy here from the old type.
13261 Past this point, we don't change OLDTYPE and NEWTYPE
13262 even if we change the types of NEWDECL and OLDDECL. */
13266 /* Merge the data types specified in the two decls. */
13267 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13268 TREE_TYPE (newdecl)
13269 = TREE_TYPE (olddecl)
13270 = TREE_TYPE (newdecl);
13272 /* Lay the type out, unless already done. */
13273 if (oldtype != TREE_TYPE (newdecl))
13275 if (TREE_TYPE (newdecl) != error_mark_node)
13276 layout_type (TREE_TYPE (newdecl));
13277 if (TREE_CODE (newdecl) != FUNCTION_DECL
13278 && TREE_CODE (newdecl) != TYPE_DECL
13279 && TREE_CODE (newdecl) != CONST_DECL)
13280 layout_decl (newdecl, 0);
13284 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13285 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
13286 DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
13287 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13288 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
13290 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13291 DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
13295 /* Keep the old rtl since we can safely use it. */
13296 COPY_DECL_RTL (olddecl, newdecl);
13298 /* Merge the type qualifiers. */
13299 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13300 && !TREE_THIS_VOLATILE (newdecl))
13301 TREE_THIS_VOLATILE (olddecl) = 0;
13302 if (TREE_READONLY (newdecl))
13303 TREE_READONLY (olddecl) = 1;
13304 if (TREE_THIS_VOLATILE (newdecl))
13306 TREE_THIS_VOLATILE (olddecl) = 1;
13307 if (TREE_CODE (newdecl) == VAR_DECL)
13308 make_var_volatile (newdecl);
13311 /* Keep source location of definition rather than declaration.
13312 Likewise, keep decl at outer scope. */
13313 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13314 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13316 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13317 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
13319 if (DECL_CONTEXT (olddecl) == 0
13320 && TREE_CODE (newdecl) != FUNCTION_DECL)
13321 DECL_CONTEXT (newdecl) = 0;
13324 /* Merge the unused-warning information. */
13325 if (DECL_IN_SYSTEM_HEADER (olddecl))
13326 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13327 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13328 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
13330 /* Merge the initialization information. */
13331 if (DECL_INITIAL (newdecl) == 0)
13332 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13334 /* Merge the section attribute.
13335 We want to issue an error if the sections conflict but that must be
13336 done later in decl_attributes since we are called before attributes
13338 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13339 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
13341 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13343 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13344 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13347 /* If cannot merge, then use the new type and qualifiers,
13348 and don't preserve the old rtl. */
13351 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13352 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13353 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13354 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13357 /* Merge the storage class information. */
13358 /* For functions, static overrides non-static. */
13359 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13361 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13362 /* This is since we don't automatically
13363 copy the attributes of NEWDECL into OLDDECL. */
13364 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13365 /* If this clears `static', clear it in the identifier too. */
13366 if (! TREE_PUBLIC (olddecl))
13367 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13369 if (DECL_EXTERNAL (newdecl))
13371 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13372 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13373 /* An extern decl does not override previous storage class. */
13374 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13378 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13379 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13382 /* If either decl says `inline', this fn is inline,
13383 unless its definition was passed already. */
13384 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13385 DECL_INLINE (olddecl) = 1;
13386 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
13388 /* Get rid of any built-in function if new arg types don't match it
13389 or if we have a function definition. */
13390 if (TREE_CODE (newdecl) == FUNCTION_DECL
13391 && DECL_BUILT_IN (olddecl)
13392 && (!types_match || new_is_definition))
13394 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13395 DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
13398 /* If redeclaring a builtin function, and not a definition,
13400 Also preserve various other info from the definition. */
13401 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13403 if (DECL_BUILT_IN (olddecl))
13405 DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
13406 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13409 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13410 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13411 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13412 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13415 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13416 But preserve olddecl's DECL_UID. */
13418 register unsigned olddecl_uid = DECL_UID (olddecl);
13420 memcpy ((char *) olddecl + sizeof (struct tree_common),
13421 (char *) newdecl + sizeof (struct tree_common),
13422 sizeof (struct tree_decl) - sizeof (struct tree_common));
13423 DECL_UID (olddecl) = olddecl_uid;
13429 /* Finish processing of a declaration;
13430 install its initial value.
13431 If the length of an array type is not known before,
13432 it must be determined now, from the initial value, or it is an error. */
13435 finish_decl (tree decl, tree init, bool is_top_level)
13437 register tree type = TREE_TYPE (decl);
13438 int was_incomplete = (DECL_SIZE (decl) == 0);
13439 bool at_top_level = (current_binding_level == global_binding_level);
13440 bool top_level = is_top_level || at_top_level;
13442 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13444 assert (!is_top_level || !at_top_level);
13446 if (TREE_CODE (decl) == PARM_DECL)
13447 assert (init == NULL_TREE);
13448 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
13449 overlaps DECL_ARG_TYPE. */
13450 else if (init == NULL_TREE)
13451 assert (DECL_INITIAL (decl) == NULL_TREE);
13453 assert (DECL_INITIAL (decl) == error_mark_node);
13455 if (init != NULL_TREE)
13457 if (TREE_CODE (decl) != TYPE_DECL)
13458 DECL_INITIAL (decl) = init;
13461 /* typedef foo = bar; store the type of bar as the type of foo. */
13462 TREE_TYPE (decl) = TREE_TYPE (init);
13463 DECL_INITIAL (decl) = init = 0;
13467 /* Deduce size of array from initialization, if not already known */
13469 if (TREE_CODE (type) == ARRAY_TYPE
13470 && TYPE_DOMAIN (type) == 0
13471 && TREE_CODE (decl) != TYPE_DECL)
13473 assert (top_level);
13474 assert (was_incomplete);
13476 layout_decl (decl, 0);
13479 if (TREE_CODE (decl) == VAR_DECL)
13481 if (DECL_SIZE (decl) == NULL_TREE
13482 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
13483 layout_decl (decl, 0);
13485 if (DECL_SIZE (decl) == NULL_TREE
13486 && (TREE_STATIC (decl)
13488 /* A static variable with an incomplete type is an error if it is
13489 initialized. Also if it is not file scope. Otherwise, let it
13490 through, but if it is not `extern' then it may cause an error
13492 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
13494 /* An automatic variable with an incomplete type is an error. */
13495 !DECL_EXTERNAL (decl)))
13497 assert ("storage size not known" == NULL);
13501 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
13502 && (DECL_SIZE (decl) != 0)
13503 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
13505 assert ("storage size not constant" == NULL);
13510 /* Output the assembler code and/or RTL code for variables and functions,
13511 unless the type is an undefined structure or union. If not, it will get
13512 done when the type is completed. */
13514 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
13516 rest_of_decl_compilation (decl, NULL,
13517 DECL_CONTEXT (decl) == 0,
13520 if (DECL_CONTEXT (decl) != 0)
13522 /* Recompute the RTL of a local array now if it used to be an
13523 incomplete type. */
13525 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
13527 /* If we used it already as memory, it must stay in memory. */
13528 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
13529 /* If it's still incomplete now, no init will save it. */
13530 if (DECL_SIZE (decl) == 0)
13531 DECL_INITIAL (decl) = 0;
13532 expand_decl (decl);
13534 /* Compute and store the initial value. */
13535 if (TREE_CODE (decl) != FUNCTION_DECL)
13536 expand_decl_init (decl);
13539 else if (TREE_CODE (decl) == TYPE_DECL)
13541 rest_of_decl_compilation (decl, NULL,
13542 DECL_CONTEXT (decl) == 0,
13546 /* At the end of a declaration, throw away any variable type sizes of types
13547 defined inside that declaration. There is no use computing them in the
13548 following function definition. */
13549 if (current_binding_level == global_binding_level)
13550 get_pending_sizes ();
13553 /* Finish up a function declaration and compile that function
13554 all the way to assembler language output. The free the storage
13555 for the function definition.
13557 This is called after parsing the body of the function definition.
13559 NESTED is nonzero if the function being finished is nested in another. */
13562 finish_function (int nested)
13564 register tree fndecl = current_function_decl;
13566 assert (fndecl != NULL_TREE);
13567 if (TREE_CODE (fndecl) != ERROR_MARK)
13570 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
13572 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
13575 /* TREE_READONLY (fndecl) = 1;
13576 This caused &foo to be of type ptr-to-const-function
13577 which then got a warning when stored in a ptr-to-function variable. */
13579 poplevel (1, 0, 1);
13581 if (TREE_CODE (fndecl) != ERROR_MARK)
13583 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
13585 /* Must mark the RESULT_DECL as being in this function. */
13587 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
13589 /* Obey `register' declarations if `setjmp' is called in this fn. */
13590 /* Generate rtl for function exit. */
13591 expand_function_end (input_filename, lineno, 0);
13593 /* If this is a nested function, protect the local variables in the stack
13594 above us from being collected while we're compiling this function. */
13596 ggc_push_context ();
13598 /* Run the optimizers and output the assembler code for this function. */
13599 rest_of_compilation (fndecl);
13601 /* Undo the GC context switch. */
13603 ggc_pop_context ();
13606 if (TREE_CODE (fndecl) != ERROR_MARK
13608 && DECL_SAVED_INSNS (fndecl) == 0)
13610 /* Stop pointing to the local nodes about to be freed. */
13611 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13612 function definition. */
13613 /* For a nested function, this is done in pop_f_function_context. */
13614 /* If rest_of_compilation set this to 0, leave it 0. */
13615 if (DECL_INITIAL (fndecl) != 0)
13616 DECL_INITIAL (fndecl) = error_mark_node;
13617 DECL_ARGUMENTS (fndecl) = 0;
13622 /* Let the error reporting routines know that we're outside a function.
13623 For a nested function, this value is used in pop_c_function_context
13624 and then reset via pop_function_context. */
13625 ffecom_outer_function_decl_ = current_function_decl = NULL;
13629 /* Plug-in replacement for identifying the name of a decl and, for a
13630 function, what we call it in diagnostics. For now, "program unit"
13631 should suffice, since it's a bit of a hassle to figure out which
13632 of several kinds of things it is. Note that it could conceivably
13633 be a statement function, which probably isn't really a program unit
13634 per se, but if that comes up, it should be easy to check (being a
13635 nested function and all). */
13637 static const char *
13638 ffe_printable_name (tree decl, int v)
13640 /* Just to keep GCC quiet about the unused variable.
13641 In theory, differing values of V should produce different
13646 if (TREE_CODE (decl) == ERROR_MARK)
13647 return "erroneous code";
13648 return IDENTIFIER_POINTER (DECL_NAME (decl));
13652 /* g77's function to print out name of current function that caused
13656 lang_print_error_function (diagnostic_context *context __attribute__((unused)),
13659 static ffeglobal last_g = NULL;
13660 static ffesymbol last_s = NULL;
13665 if ((ffecom_primary_entry_ == NULL)
13666 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
13674 g = ffesymbol_global (ffecom_primary_entry_);
13675 if (ffecom_nested_entry_ == NULL)
13677 s = ffecom_primary_entry_;
13678 kind = _(ffeinfo_kind_message (ffesymbol_kind (s)));
13682 s = ffecom_nested_entry_;
13683 kind = _("In statement function");
13687 if ((last_g != g) || (last_s != s))
13690 fprintf (stderr, "%s: ", file);
13693 fprintf (stderr, _("Outside of any program unit:\n"));
13696 const char *name = ffesymbol_text (s);
13698 fprintf (stderr, "%s `%s':\n", kind, name);
13706 /* Similar to `lookup_name' but look only at current binding level. */
13709 lookup_name_current_level (tree name)
13713 if (current_binding_level == global_binding_level)
13714 return IDENTIFIER_GLOBAL_VALUE (name);
13716 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
13719 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
13720 if (DECL_NAME (t) == name)
13726 /* Create a new `struct binding_level'. */
13728 static struct binding_level *
13729 make_binding_level ()
13732 return (struct binding_level *) xmalloc (sizeof (struct binding_level));
13735 /* Save and restore the variables in this file and elsewhere
13736 that keep track of the progress of compilation of the current function.
13737 Used for nested functions. */
13741 struct f_function *next;
13743 tree shadowed_labels;
13744 struct binding_level *binding_level;
13747 struct f_function *f_function_chain;
13749 /* Restore the variables used during compilation of a C function. */
13752 pop_f_function_context ()
13754 struct f_function *p = f_function_chain;
13757 /* Bring back all the labels that were shadowed. */
13758 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
13759 if (DECL_NAME (TREE_VALUE (link)) != 0)
13760 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
13761 = TREE_VALUE (link);
13763 if (current_function_decl != error_mark_node
13764 && DECL_SAVED_INSNS (current_function_decl) == 0)
13766 /* Stop pointing to the local nodes about to be freed. */
13767 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13768 function definition. */
13769 DECL_INITIAL (current_function_decl) = error_mark_node;
13770 DECL_ARGUMENTS (current_function_decl) = 0;
13773 pop_function_context ();
13775 f_function_chain = p->next;
13777 named_labels = p->named_labels;
13778 shadowed_labels = p->shadowed_labels;
13779 current_binding_level = p->binding_level;
13784 /* Save and reinitialize the variables
13785 used during compilation of a C function. */
13788 push_f_function_context ()
13790 struct f_function *p
13791 = (struct f_function *) xmalloc (sizeof (struct f_function));
13793 push_function_context ();
13795 p->next = f_function_chain;
13796 f_function_chain = p;
13798 p->named_labels = named_labels;
13799 p->shadowed_labels = shadowed_labels;
13800 p->binding_level = current_binding_level;
13804 push_parm_decl (tree parm)
13806 int old_immediate_size_expand = immediate_size_expand;
13808 /* Don't try computing parm sizes now -- wait till fn is called. */
13810 immediate_size_expand = 0;
13812 /* Fill in arg stuff. */
13814 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
13815 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
13816 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
13818 parm = pushdecl (parm);
13820 immediate_size_expand = old_immediate_size_expand;
13822 finish_decl (parm, NULL_TREE, FALSE);
13825 /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
13828 pushdecl_top_level (x)
13832 register struct binding_level *b = current_binding_level;
13833 register tree f = current_function_decl;
13835 current_binding_level = global_binding_level;
13836 current_function_decl = NULL_TREE;
13838 current_binding_level = b;
13839 current_function_decl = f;
13843 /* Store the list of declarations of the current level.
13844 This is done for the parameter declarations of a function being defined,
13845 after they are modified in the light of any missing parameters. */
13851 return current_binding_level->names = decls;
13854 /* Store the parameter declarations into the current function declaration.
13855 This is called after parsing the parameter declarations, before
13856 digesting the body of the function.
13858 For an old-style definition, modify the function's type
13859 to specify at least the number of arguments. */
13862 store_parm_decls (int is_main_program UNUSED)
13864 register tree fndecl = current_function_decl;
13866 if (fndecl == error_mark_node)
13869 /* This is a chain of PARM_DECLs from old-style parm declarations. */
13870 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
13872 /* Initialize the RTL code for the function. */
13874 init_function_start (fndecl, input_filename, lineno);
13876 /* Set up parameters and prepare for return, for the function. */
13878 expand_function_start (fndecl, 0);
13882 start_decl (tree decl, bool is_top_level)
13885 bool at_top_level = (current_binding_level == global_binding_level);
13886 bool top_level = is_top_level || at_top_level;
13888 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13890 assert (!is_top_level || !at_top_level);
13892 if (DECL_INITIAL (decl) != NULL_TREE)
13894 assert (DECL_INITIAL (decl) == error_mark_node);
13895 assert (!DECL_EXTERNAL (decl));
13897 else if (top_level)
13898 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
13900 /* For Fortran, we by default put things in .common when possible. */
13901 DECL_COMMON (decl) = 1;
13903 /* Add this decl to the current binding level. TEM may equal DECL or it may
13904 be a previous decl of the same name. */
13906 tem = pushdecl_top_level (decl);
13908 tem = pushdecl (decl);
13910 /* For a local variable, define the RTL now. */
13912 /* But not if this is a duplicate decl and we preserved the rtl from the
13913 previous one (which may or may not happen). */
13914 && !DECL_RTL_SET_P (tem))
13916 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
13918 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
13919 && DECL_INITIAL (tem) != 0)
13926 /* Create the FUNCTION_DECL for a function definition.
13927 DECLSPECS and DECLARATOR are the parts of the declaration;
13928 they describe the function's name and the type it returns,
13929 but twisted together in a fashion that parallels the syntax of C.
13931 This function creates a binding context for the function body
13932 as well as setting up the FUNCTION_DECL in current_function_decl.
13934 Returns 1 on success. If the DECLARATOR is not suitable for a function
13935 (it defines a datum instead), we return 0, which tells
13936 ffe_parse_file to report a parse error.
13938 NESTED is nonzero for a function nested within another function. */
13941 start_function (tree name, tree type, int nested, int public)
13945 int old_immediate_size_expand = immediate_size_expand;
13948 shadowed_labels = 0;
13950 /* Don't expand any sizes in the return type of the function. */
13951 immediate_size_expand = 0;
13956 assert (current_function_decl != NULL_TREE);
13957 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
13961 assert (current_function_decl == NULL_TREE);
13964 if (TREE_CODE (type) == ERROR_MARK)
13965 decl1 = current_function_decl = error_mark_node;
13968 decl1 = build_decl (FUNCTION_DECL,
13971 TREE_PUBLIC (decl1) = public ? 1 : 0;
13973 DECL_INLINE (decl1) = 1;
13974 TREE_STATIC (decl1) = 1;
13975 DECL_EXTERNAL (decl1) = 0;
13977 announce_function (decl1);
13979 /* Make the init_value nonzero so pushdecl knows this is not tentative.
13980 error_mark_node is replaced below (in poplevel) with the BLOCK. */
13981 DECL_INITIAL (decl1) = error_mark_node;
13983 /* Record the decl so that the function name is defined. If we already have
13984 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
13986 current_function_decl = pushdecl (decl1);
13990 ffecom_outer_function_decl_ = current_function_decl;
13993 current_binding_level->prep_state = 2;
13995 if (TREE_CODE (current_function_decl) != ERROR_MARK)
13997 make_decl_rtl (current_function_decl, NULL);
13999 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14000 DECL_RESULT (current_function_decl)
14001 = build_decl (RESULT_DECL, NULL_TREE, restype);
14004 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14005 TREE_ADDRESSABLE (current_function_decl) = 1;
14007 immediate_size_expand = old_immediate_size_expand;
14010 /* Here are the public functions the GNU back end needs. */
14013 convert (type, expr)
14016 register tree e = expr;
14017 register enum tree_code code = TREE_CODE (type);
14019 if (type == TREE_TYPE (e)
14020 || TREE_CODE (e) == ERROR_MARK)
14022 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14023 return fold (build1 (NOP_EXPR, type, e));
14024 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14025 || code == ERROR_MARK)
14026 return error_mark_node;
14027 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14029 assert ("void value not ignored as it ought to be" == NULL);
14030 return error_mark_node;
14032 if (code == VOID_TYPE)
14033 return build1 (CONVERT_EXPR, type, e);
14034 if ((code != RECORD_TYPE)
14035 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14036 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14038 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14039 return fold (convert_to_integer (type, e));
14040 if (code == POINTER_TYPE)
14041 return fold (convert_to_pointer (type, e));
14042 if (code == REAL_TYPE)
14043 return fold (convert_to_real (type, e));
14044 if (code == COMPLEX_TYPE)
14045 return fold (convert_to_complex (type, e));
14046 if (code == RECORD_TYPE)
14047 return fold (ffecom_convert_to_complex_ (type, e));
14049 assert ("conversion to non-scalar type requested" == NULL);
14050 return error_mark_node;
14053 /* Return the list of declarations of the current level.
14054 Note that this list is in reverse order unless/until
14055 you nreverse it; and when you do nreverse it, you must
14056 store the result back using `storedecls' or you will lose. */
14061 return current_binding_level->names;
14064 /* Nonzero if we are currently in the global binding level. */
14067 global_bindings_p ()
14069 return current_binding_level == global_binding_level;
14072 /* Print an error message for invalid use of an incomplete type.
14073 VALUE is the expression that was used (or 0 if that isn't known)
14074 and TYPE is the type that was invalid. */
14077 incomplete_type_error (value, type)
14081 if (TREE_CODE (type) == ERROR_MARK)
14084 assert ("incomplete type?!?" == NULL);
14087 /* Mark ARG for GC. */
14089 mark_binding_level (void *arg)
14091 struct binding_level *level = *(struct binding_level **) arg;
14095 ggc_mark_tree (level->names);
14096 ggc_mark_tree (level->blocks);
14097 ggc_mark_tree (level->this_block);
14098 level = level->level_chain;
14103 ffecom_init_decl_processing ()
14105 static tree *const tree_roots[] = {
14106 ¤t_function_decl,
14108 &ffecom_tree_fun_type_void,
14109 &ffecom_integer_zero_node,
14110 &ffecom_integer_one_node,
14111 &ffecom_tree_subr_type,
14112 &ffecom_tree_ptr_to_subr_type,
14113 &ffecom_tree_blockdata_type,
14114 &ffecom_tree_xargc_,
14115 &ffecom_f2c_integer_type_node,
14116 &ffecom_f2c_ptr_to_integer_type_node,
14117 &ffecom_f2c_address_type_node,
14118 &ffecom_f2c_real_type_node,
14119 &ffecom_f2c_ptr_to_real_type_node,
14120 &ffecom_f2c_doublereal_type_node,
14121 &ffecom_f2c_complex_type_node,
14122 &ffecom_f2c_doublecomplex_type_node,
14123 &ffecom_f2c_longint_type_node,
14124 &ffecom_f2c_logical_type_node,
14125 &ffecom_f2c_flag_type_node,
14126 &ffecom_f2c_ftnlen_type_node,
14127 &ffecom_f2c_ftnlen_zero_node,
14128 &ffecom_f2c_ftnlen_one_node,
14129 &ffecom_f2c_ftnlen_two_node,
14130 &ffecom_f2c_ptr_to_ftnlen_type_node,
14131 &ffecom_f2c_ftnint_type_node,
14132 &ffecom_f2c_ptr_to_ftnint_type_node,
14133 &ffecom_outer_function_decl_,
14134 &ffecom_previous_function_decl_,
14135 &ffecom_which_entrypoint_decl_,
14136 &ffecom_float_zero_,
14137 &ffecom_float_half_,
14138 &ffecom_double_zero_,
14139 &ffecom_double_half_,
14140 &ffecom_func_result_,
14141 &ffecom_func_length_,
14142 &ffecom_multi_type_node_,
14143 &ffecom_multi_retval_,
14151 /* Record our roots. */
14152 for (i = 0; i < ARRAY_SIZE (tree_roots); i++)
14153 ggc_add_tree_root (tree_roots[i], 1);
14154 ggc_add_tree_root (&ffecom_tree_type[0][0],
14155 FFEINFO_basictype*FFEINFO_kindtype);
14156 ggc_add_tree_root (&ffecom_tree_fun_type[0][0],
14157 FFEINFO_basictype*FFEINFO_kindtype);
14158 ggc_add_tree_root (&ffecom_tree_ptr_to_fun_type[0][0],
14159 FFEINFO_basictype*FFEINFO_kindtype);
14160 ggc_add_tree_root (ffecom_gfrt_, FFECOM_gfrt);
14161 ggc_add_root (¤t_binding_level, 1, sizeof current_binding_level,
14162 mark_binding_level);
14163 ggc_add_root (&free_binding_level, 1, sizeof current_binding_level,
14164 mark_binding_level);
14165 ggc_add_root (&tracker_head, 1, sizeof tracker_head, mark_tracker_head);
14170 /* Delete the node BLOCK from the current binding level.
14171 This is used for the block inside a stmt expr ({...})
14172 so that the block can be reinserted where appropriate. */
14175 delete_block (block)
14179 if (current_binding_level->blocks == block)
14180 current_binding_level->blocks = TREE_CHAIN (block);
14181 for (t = current_binding_level->blocks; t;)
14183 if (TREE_CHAIN (t) == block)
14184 TREE_CHAIN (t) = TREE_CHAIN (block);
14186 t = TREE_CHAIN (t);
14188 TREE_CHAIN (block) = NULL;
14189 /* Clear TREE_USED which is always set by poplevel.
14190 The flag is set again if insert_block is called. */
14191 TREE_USED (block) = 0;
14195 insert_block (block)
14198 TREE_USED (block) = 1;
14199 current_binding_level->blocks
14200 = chainon (current_binding_level->blocks, block);
14203 /* Each front end provides its own. */
14204 static const char *ffe_init PARAMS ((const char *));
14205 static void ffe_finish PARAMS ((void));
14206 static void ffe_init_options PARAMS ((void));
14207 static void ffe_print_identifier PARAMS ((FILE *, tree, int));
14209 #undef LANG_HOOKS_NAME
14210 #define LANG_HOOKS_NAME "GNU F77"
14211 #undef LANG_HOOKS_INIT
14212 #define LANG_HOOKS_INIT ffe_init
14213 #undef LANG_HOOKS_FINISH
14214 #define LANG_HOOKS_FINISH ffe_finish
14215 #undef LANG_HOOKS_INIT_OPTIONS
14216 #define LANG_HOOKS_INIT_OPTIONS ffe_init_options
14217 #undef LANG_HOOKS_DECODE_OPTION
14218 #define LANG_HOOKS_DECODE_OPTION ffe_decode_option
14219 #undef LANG_HOOKS_PARSE_FILE
14220 #define LANG_HOOKS_PARSE_FILE ffe_parse_file
14221 #undef LANG_HOOKS_PRINT_IDENTIFIER
14222 #define LANG_HOOKS_PRINT_IDENTIFIER ffe_print_identifier
14223 #undef LANG_HOOKS_DECL_PRINTABLE_NAME
14224 #define LANG_HOOKS_DECL_PRINTABLE_NAME ffe_printable_name
14226 /* We do not wish to use alias-set based aliasing at all. Used in the
14227 extreme (every object with its own set, with equivalences recorded) it
14228 might be helpful, but there are problems when it comes to inlining. We
14229 get on ok with flag_argument_noalias, and alias-set aliasing does
14230 currently limit how stack slots can be reused, which is a lose. */
14231 #undef LANG_HOOKS_GET_ALIAS_SET
14232 #define LANG_HOOKS_GET_ALIAS_SET hook_get_alias_set_0
14234 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
14236 /* Table indexed by tree code giving a string containing a character
14237 classifying the tree code. Possibilities are
14238 t, d, s, c, r, <, 1, 2 and e. See tree.def for details. */
14240 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
14242 const char tree_code_type[] = {
14243 #include "tree.def"
14247 /* Table indexed by tree code giving number of expression
14248 operands beyond the fixed part of the node structure.
14249 Not used for types or decls. */
14251 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
14253 const unsigned char tree_code_length[] = {
14254 #include "tree.def"
14258 /* Names of tree components.
14259 Used for printing out the tree and error messages. */
14260 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
14262 const char *const tree_code_name[] = {
14263 #include "tree.def"
14267 static const char *
14268 ffe_init (filename)
14269 const char *filename;
14271 /* Open input file. */
14272 if (filename == 0 || !strcmp (filename, "-"))
14275 filename = "stdin";
14278 finput = fopen (filename, "r");
14280 fatal_io_error ("can't open %s", filename);
14282 #ifdef IO_BUFFER_SIZE
14283 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14286 ffecom_init_decl_processing ();
14287 print_error_function = lang_print_error_function;
14289 /* If the file is output from cpp, it should contain a first line
14290 `# 1 "real-filename"', and the current design of gcc (toplev.c
14291 in particular and the way it sets up information relied on by
14292 INCLUDE) requires that we read this now, and store the
14293 "real-filename" info in master_input_filename. Ask the lexer
14294 to try doing this. */
14295 ffelex_hash_kludge (finput);
14297 /* FIXME: The ffelex_hash_kludge code needs to be cleaned up to
14298 return the new file name. */
14299 if (main_input_filename)
14300 filename = main_input_filename;
14308 ffe_terminate_0 ();
14310 if (ffe_is_ffedebug ())
14311 malloc_pool_display (malloc_pool_image ());
14317 ffe_init_options ()
14319 /* Set default options for Fortran. */
14320 flag_move_all_movables = 1;
14321 flag_reduce_all_givs = 1;
14322 flag_argument_noalias = 2;
14323 flag_merge_constants = 2;
14324 flag_errno_math = 0;
14325 flag_complex_divide_method = 1;
14329 mark_addressable (exp)
14332 register tree x = exp;
14334 switch (TREE_CODE (x))
14337 case COMPONENT_REF:
14339 x = TREE_OPERAND (x, 0);
14343 TREE_ADDRESSABLE (x) = 1;
14350 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14351 && DECL_NONLOCAL (x))
14353 if (TREE_PUBLIC (x))
14355 assert ("address of global register var requested" == NULL);
14358 assert ("address of register variable requested" == NULL);
14360 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14362 if (TREE_PUBLIC (x))
14364 assert ("address of global register var requested" == NULL);
14367 assert ("address of register var requested" == NULL);
14369 put_var_into_stack (x);
14372 case FUNCTION_DECL:
14373 TREE_ADDRESSABLE (x) = 1;
14374 #if 0 /* poplevel deals with this now. */
14375 if (DECL_CONTEXT (x) == 0)
14376 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14384 /* Exit a binding level.
14385 Pop the level off, and restore the state of the identifier-decl mappings
14386 that were in effect when this level was entered.
14388 If KEEP is nonzero, this level had explicit declarations, so
14389 and create a "block" (a BLOCK node) for the level
14390 to record its declarations and subblocks for symbol table output.
14392 If FUNCTIONBODY is nonzero, this level is the body of a function,
14393 so create a block as if KEEP were set and also clear out all
14396 If REVERSE is nonzero, reverse the order of decls before putting
14397 them into the BLOCK. */
14400 poplevel (keep, reverse, functionbody)
14405 register tree link;
14406 /* The chain of decls was accumulated in reverse order.
14407 Put it into forward order, just for cleanliness. */
14409 tree subblocks = current_binding_level->blocks;
14412 int block_previously_created;
14414 /* Get the decls in the order they were written.
14415 Usually current_binding_level->names is in reverse order.
14416 But parameter decls were previously put in forward order. */
14419 current_binding_level->names
14420 = decls = nreverse (current_binding_level->names);
14422 decls = current_binding_level->names;
14424 /* Output any nested inline functions within this block
14425 if they weren't already output. */
14427 for (decl = decls; decl; decl = TREE_CHAIN (decl))
14428 if (TREE_CODE (decl) == FUNCTION_DECL
14429 && ! TREE_ASM_WRITTEN (decl)
14430 && DECL_INITIAL (decl) != 0
14431 && TREE_ADDRESSABLE (decl))
14433 /* If this decl was copied from a file-scope decl
14434 on account of a block-scope extern decl,
14435 propagate TREE_ADDRESSABLE to the file-scope decl.
14437 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
14438 true, since then the decl goes through save_for_inline_copying. */
14439 if (DECL_ABSTRACT_ORIGIN (decl) != 0
14440 && DECL_ABSTRACT_ORIGIN (decl) != decl)
14441 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
14442 else if (DECL_SAVED_INSNS (decl) != 0)
14444 push_function_context ();
14445 output_inline_function (decl);
14446 pop_function_context ();
14450 /* If there were any declarations or structure tags in that level,
14451 or if this level is a function body,
14452 create a BLOCK to record them for the life of this function. */
14455 block_previously_created = (current_binding_level->this_block != 0);
14456 if (block_previously_created)
14457 block = current_binding_level->this_block;
14458 else if (keep || functionbody)
14459 block = make_node (BLOCK);
14462 BLOCK_VARS (block) = decls;
14463 BLOCK_SUBBLOCKS (block) = subblocks;
14466 /* In each subblock, record that this is its superior. */
14468 for (link = subblocks; link; link = TREE_CHAIN (link))
14469 BLOCK_SUPERCONTEXT (link) = block;
14471 /* Clear out the meanings of the local variables of this level. */
14473 for (link = decls; link; link = TREE_CHAIN (link))
14475 if (DECL_NAME (link) != 0)
14477 /* If the ident. was used or addressed via a local extern decl,
14478 don't forget that fact. */
14479 if (DECL_EXTERNAL (link))
14481 if (TREE_USED (link))
14482 TREE_USED (DECL_NAME (link)) = 1;
14483 if (TREE_ADDRESSABLE (link))
14484 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
14486 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
14490 /* If the level being exited is the top level of a function,
14491 check over all the labels, and clear out the current
14492 (function local) meanings of their names. */
14496 /* If this is the top level block of a function,
14497 the vars are the function's parameters.
14498 Don't leave them in the BLOCK because they are
14499 found in the FUNCTION_DECL instead. */
14501 BLOCK_VARS (block) = 0;
14504 /* Pop the current level, and free the structure for reuse. */
14507 register struct binding_level *level = current_binding_level;
14508 current_binding_level = current_binding_level->level_chain;
14510 level->level_chain = free_binding_level;
14511 free_binding_level = level;
14514 /* Dispose of the block that we just made inside some higher level. */
14516 && current_function_decl != error_mark_node)
14517 DECL_INITIAL (current_function_decl) = block;
14520 if (!block_previously_created)
14521 current_binding_level->blocks
14522 = chainon (current_binding_level->blocks, block);
14524 /* If we did not make a block for the level just exited,
14525 any blocks made for inner levels
14526 (since they cannot be recorded as subblocks in that level)
14527 must be carried forward so they will later become subblocks
14528 of something else. */
14529 else if (subblocks)
14530 current_binding_level->blocks
14531 = chainon (current_binding_level->blocks, subblocks);
14534 TREE_USED (block) = 1;
14539 ffe_print_identifier (file, node, indent)
14544 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
14545 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
14548 /* Record a decl-node X as belonging to the current lexical scope.
14549 Check for errors (such as an incompatible declaration for the same
14550 name already seen in the same scope).
14552 Returns either X or an old decl for the same name.
14553 If an old decl is returned, it may have been smashed
14554 to agree with what X says. */
14561 register tree name = DECL_NAME (x);
14562 register struct binding_level *b = current_binding_level;
14564 if ((TREE_CODE (x) == FUNCTION_DECL)
14565 && (DECL_INITIAL (x) == 0)
14566 && DECL_EXTERNAL (x))
14567 DECL_CONTEXT (x) = NULL_TREE;
14569 DECL_CONTEXT (x) = current_function_decl;
14573 if (IDENTIFIER_INVENTED (name))
14575 DECL_ARTIFICIAL (x) = 1;
14576 DECL_IN_SYSTEM_HEADER (x) = 1;
14579 t = lookup_name_current_level (name);
14581 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
14583 /* Don't push non-parms onto list for parms until we understand
14584 why we're doing this and whether it works. */
14586 assert ((b == global_binding_level)
14587 || !ffecom_transform_only_dummies_
14588 || TREE_CODE (x) == PARM_DECL);
14590 if ((t != NULL_TREE) && duplicate_decls (x, t))
14593 /* If we are processing a typedef statement, generate a whole new
14594 ..._TYPE node (which will be just an variant of the existing
14595 ..._TYPE node with identical properties) and then install the
14596 TYPE_DECL node generated to represent the typedef name as the
14597 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
14599 The whole point here is to end up with a situation where each and every
14600 ..._TYPE node the compiler creates will be uniquely associated with
14601 AT MOST one node representing a typedef name. This way, even though
14602 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
14603 (i.e. "typedef name") nodes very early on, later parts of the
14604 compiler can always do the reverse translation and get back the
14605 corresponding typedef name. For example, given:
14607 typedef struct S MY_TYPE; MY_TYPE object;
14609 Later parts of the compiler might only know that `object' was of type
14610 `struct S' if it were not for code just below. With this code
14611 however, later parts of the compiler see something like:
14613 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
14615 And they can then deduce (from the node for type struct S') that the
14616 original object declaration was:
14620 Being able to do this is important for proper support of protoize, and
14621 also for generating precise symbolic debugging information which
14622 takes full account of the programmer's (typedef) vocabulary.
14624 Obviously, we don't want to generate a duplicate ..._TYPE node if the
14625 TYPE_DECL node that we are now processing really represents a
14626 standard built-in type.
14628 Since all standard types are effectively declared at line zero in the
14629 source file, we can easily check to see if we are working on a
14630 standard type by checking the current value of lineno. */
14632 if (TREE_CODE (x) == TYPE_DECL)
14634 if (DECL_SOURCE_LINE (x) == 0)
14636 if (TYPE_NAME (TREE_TYPE (x)) == 0)
14637 TYPE_NAME (TREE_TYPE (x)) = x;
14639 else if (TREE_TYPE (x) != error_mark_node)
14641 tree tt = TREE_TYPE (x);
14643 tt = build_type_copy (tt);
14644 TYPE_NAME (tt) = x;
14645 TREE_TYPE (x) = tt;
14649 /* This name is new in its binding level. Install the new declaration
14651 if (b == global_binding_level)
14652 IDENTIFIER_GLOBAL_VALUE (name) = x;
14654 IDENTIFIER_LOCAL_VALUE (name) = x;
14657 /* Put decls on list in reverse order. We will reverse them later if
14659 TREE_CHAIN (x) = b->names;
14665 /* Nonzero if the current level needs to have a BLOCK made. */
14672 for (decl = current_binding_level->names;
14674 decl = TREE_CHAIN (decl))
14676 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
14677 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
14678 /* Currently, there aren't supposed to be non-artificial names
14679 at other than the top block for a function -- they're
14680 believed to always be temps. But it's wise to check anyway. */
14686 /* Enter a new binding level.
14687 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
14688 not for that of tags. */
14691 pushlevel (tag_transparent)
14692 int tag_transparent;
14694 register struct binding_level *newlevel = NULL_BINDING_LEVEL;
14696 assert (! tag_transparent);
14698 if (current_binding_level == global_binding_level)
14703 /* Reuse or create a struct for this binding level. */
14705 if (free_binding_level)
14707 newlevel = free_binding_level;
14708 free_binding_level = free_binding_level->level_chain;
14712 newlevel = make_binding_level ();
14715 /* Add this level to the front of the chain (stack) of levels that
14718 *newlevel = clear_binding_level;
14719 newlevel->level_chain = current_binding_level;
14720 current_binding_level = newlevel;
14723 /* Set the BLOCK node for the innermost scope
14724 (the one we are currently in). */
14728 register tree block;
14730 current_binding_level->this_block = block;
14731 current_binding_level->names = chainon (current_binding_level->names,
14732 BLOCK_VARS (block));
14733 current_binding_level->blocks = chainon (current_binding_level->blocks,
14734 BLOCK_SUBBLOCKS (block));
14738 signed_or_unsigned_type (unsignedp, type)
14744 if (! INTEGRAL_TYPE_P (type))
14746 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
14747 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
14748 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
14749 return unsignedp ? unsigned_type_node : integer_type_node;
14750 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
14751 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
14752 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
14753 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
14754 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
14755 return (unsignedp ? long_long_unsigned_type_node
14756 : long_long_integer_type_node);
14758 type2 = type_for_size (TYPE_PRECISION (type), unsignedp);
14759 if (type2 == NULL_TREE)
14769 tree type1 = TYPE_MAIN_VARIANT (type);
14770 ffeinfoKindtype kt;
14773 if (type1 == unsigned_char_type_node || type1 == char_type_node)
14774 return signed_char_type_node;
14775 if (type1 == unsigned_type_node)
14776 return integer_type_node;
14777 if (type1 == short_unsigned_type_node)
14778 return short_integer_type_node;
14779 if (type1 == long_unsigned_type_node)
14780 return long_integer_type_node;
14781 if (type1 == long_long_unsigned_type_node)
14782 return long_long_integer_type_node;
14783 #if 0 /* gcc/c-* files only */
14784 if (type1 == unsigned_intDI_type_node)
14785 return intDI_type_node;
14786 if (type1 == unsigned_intSI_type_node)
14787 return intSI_type_node;
14788 if (type1 == unsigned_intHI_type_node)
14789 return intHI_type_node;
14790 if (type1 == unsigned_intQI_type_node)
14791 return intQI_type_node;
14794 type2 = type_for_size (TYPE_PRECISION (type1), 0);
14795 if (type2 != NULL_TREE)
14798 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
14800 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
14802 if (type1 == type2)
14803 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
14809 /* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
14810 or validate its data type for an `if' or `while' statement or ?..: exp.
14812 This preparation consists of taking the ordinary
14813 representation of an expression expr and producing a valid tree
14814 boolean expression describing whether expr is nonzero. We could
14815 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
14816 but we optimize comparisons, &&, ||, and !.
14818 The resulting type should always be `integer_type_node'. */
14821 truthvalue_conversion (expr)
14824 if (TREE_CODE (expr) == ERROR_MARK)
14827 #if 0 /* This appears to be wrong for C++. */
14828 /* These really should return error_mark_node after 2.4 is stable.
14829 But not all callers handle ERROR_MARK properly. */
14830 switch (TREE_CODE (TREE_TYPE (expr)))
14833 error ("struct type value used where scalar is required");
14834 return integer_zero_node;
14837 error ("union type value used where scalar is required");
14838 return integer_zero_node;
14841 error ("array type value used where scalar is required");
14842 return integer_zero_node;
14849 switch (TREE_CODE (expr))
14851 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14852 or comparison expressions as truth values at this level. */
14854 case COMPONENT_REF:
14855 /* A one-bit unsigned bit-field is already acceptable. */
14856 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
14857 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
14863 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14864 or comparison expressions as truth values at this level. */
14866 if (integer_zerop (TREE_OPERAND (expr, 1)))
14867 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
14869 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
14870 case TRUTH_ANDIF_EXPR:
14871 case TRUTH_ORIF_EXPR:
14872 case TRUTH_AND_EXPR:
14873 case TRUTH_OR_EXPR:
14874 case TRUTH_XOR_EXPR:
14875 TREE_TYPE (expr) = integer_type_node;
14882 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
14885 return real_zerop (expr) ? integer_zero_node : integer_one_node;
14888 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
14889 return build (COMPOUND_EXPR, integer_type_node,
14890 TREE_OPERAND (expr, 0), integer_one_node);
14892 return integer_one_node;
14895 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
14896 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
14898 truthvalue_conversion (TREE_OPERAND (expr, 0)),
14899 truthvalue_conversion (TREE_OPERAND (expr, 1)));
14905 /* These don't change whether an object is non-zero or zero. */
14906 return truthvalue_conversion (TREE_OPERAND (expr, 0));
14910 /* These don't change whether an object is zero or non-zero, but
14911 we can't ignore them if their second arg has side-effects. */
14912 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
14913 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
14914 truthvalue_conversion (TREE_OPERAND (expr, 0)));
14916 return truthvalue_conversion (TREE_OPERAND (expr, 0));
14919 /* Distribute the conversion into the arms of a COND_EXPR. */
14920 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
14921 truthvalue_conversion (TREE_OPERAND (expr, 1)),
14922 truthvalue_conversion (TREE_OPERAND (expr, 2))));
14925 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
14926 since that affects how `default_conversion' will behave. */
14927 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
14928 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
14930 /* fall through... */
14932 /* If this is widening the argument, we can ignore it. */
14933 if (TYPE_PRECISION (TREE_TYPE (expr))
14934 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
14935 return truthvalue_conversion (TREE_OPERAND (expr, 0));
14939 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
14941 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
14942 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
14944 /* fall through... */
14946 /* This and MINUS_EXPR can be changed into a comparison of the
14948 if (TREE_TYPE (TREE_OPERAND (expr, 0))
14949 == TREE_TYPE (TREE_OPERAND (expr, 1)))
14950 return ffecom_2 (NE_EXPR, integer_type_node,
14951 TREE_OPERAND (expr, 0),
14952 TREE_OPERAND (expr, 1));
14953 return ffecom_2 (NE_EXPR, integer_type_node,
14954 TREE_OPERAND (expr, 0),
14955 fold (build1 (NOP_EXPR,
14956 TREE_TYPE (TREE_OPERAND (expr, 0)),
14957 TREE_OPERAND (expr, 1))));
14960 if (integer_onep (TREE_OPERAND (expr, 1)))
14965 #if 0 /* No such thing in Fortran. */
14966 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
14967 warning ("suggest parentheses around assignment used as truth value");
14975 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
14977 ((TREE_SIDE_EFFECTS (expr)
14978 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
14980 truthvalue_conversion (ffecom_1 (REALPART_EXPR,
14981 TREE_TYPE (TREE_TYPE (expr)),
14983 truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
14984 TREE_TYPE (TREE_TYPE (expr)),
14987 return ffecom_2 (NE_EXPR, integer_type_node,
14989 convert (TREE_TYPE (expr), integer_zero_node));
14993 type_for_mode (mode, unsignedp)
14994 enum machine_mode mode;
15001 if (mode == TYPE_MODE (integer_type_node))
15002 return unsignedp ? unsigned_type_node : integer_type_node;
15004 if (mode == TYPE_MODE (signed_char_type_node))
15005 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15007 if (mode == TYPE_MODE (short_integer_type_node))
15008 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15010 if (mode == TYPE_MODE (long_integer_type_node))
15011 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15013 if (mode == TYPE_MODE (long_long_integer_type_node))
15014 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
15016 #if HOST_BITS_PER_WIDE_INT >= 64
15017 if (mode == TYPE_MODE (intTI_type_node))
15018 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
15021 if (mode == TYPE_MODE (float_type_node))
15022 return float_type_node;
15024 if (mode == TYPE_MODE (double_type_node))
15025 return double_type_node;
15027 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
15028 return build_pointer_type (char_type_node);
15030 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
15031 return build_pointer_type (integer_type_node);
15033 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
15034 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
15036 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
15037 && (mode == TYPE_MODE (t)))
15039 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
15040 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
15050 type_for_size (bits, unsignedp)
15054 ffeinfoKindtype kt;
15057 if (bits == TYPE_PRECISION (integer_type_node))
15058 return unsignedp ? unsigned_type_node : integer_type_node;
15060 if (bits == TYPE_PRECISION (signed_char_type_node))
15061 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15063 if (bits == TYPE_PRECISION (short_integer_type_node))
15064 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15066 if (bits == TYPE_PRECISION (long_integer_type_node))
15067 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15069 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15070 return (unsignedp ? long_long_unsigned_type_node
15071 : long_long_integer_type_node);
15073 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15075 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15077 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15078 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15086 unsigned_type (type)
15089 tree type1 = TYPE_MAIN_VARIANT (type);
15090 ffeinfoKindtype kt;
15093 if (type1 == signed_char_type_node || type1 == char_type_node)
15094 return unsigned_char_type_node;
15095 if (type1 == integer_type_node)
15096 return unsigned_type_node;
15097 if (type1 == short_integer_type_node)
15098 return short_unsigned_type_node;
15099 if (type1 == long_integer_type_node)
15100 return long_unsigned_type_node;
15101 if (type1 == long_long_integer_type_node)
15102 return long_long_unsigned_type_node;
15103 #if 0 /* gcc/c-* files only */
15104 if (type1 == intDI_type_node)
15105 return unsigned_intDI_type_node;
15106 if (type1 == intSI_type_node)
15107 return unsigned_intSI_type_node;
15108 if (type1 == intHI_type_node)
15109 return unsigned_intHI_type_node;
15110 if (type1 == intQI_type_node)
15111 return unsigned_intQI_type_node;
15114 type2 = type_for_size (TYPE_PRECISION (type1), 1);
15115 if (type2 != NULL_TREE)
15118 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15120 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15122 if (type1 == type2)
15123 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15131 union tree_node *t ATTRIBUTE_UNUSED;
15133 if (TREE_CODE (t) == IDENTIFIER_NODE)
15135 struct lang_identifier *i = (struct lang_identifier *) t;
15136 ggc_mark_tree (IDENTIFIER_GLOBAL_VALUE (i));
15137 ggc_mark_tree (IDENTIFIER_LOCAL_VALUE (i));
15138 ggc_mark_tree (IDENTIFIER_LABEL_VALUE (i));
15140 else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
15141 ggc_mark (TYPE_LANG_SPECIFIC (t));
15144 /* From gcc/cccp.c, the code to handle -I. */
15146 /* Skip leading "./" from a directory name.
15147 This may yield the empty string, which represents the current directory. */
15149 static const char *
15150 skip_redundant_dir_prefix (const char *dir)
15152 while (dir[0] == '.' && dir[1] == '/')
15153 for (dir += 2; *dir == '/'; dir++)
15155 if (dir[0] == '.' && !dir[1])
15160 /* The file_name_map structure holds a mapping of file names for a
15161 particular directory. This mapping is read from the file named
15162 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15163 map filenames on a file system with severe filename restrictions,
15164 such as DOS. The format of the file name map file is just a series
15165 of lines with two tokens on each line. The first token is the name
15166 to map, and the second token is the actual name to use. */
15168 struct file_name_map
15170 struct file_name_map *map_next;
15175 #define FILE_NAME_MAP_FILE "header.gcc"
15177 /* Current maximum length of directory names in the search path
15178 for include files. (Altered as we get more of them.) */
15180 static int max_include_len = 0;
15182 struct file_name_list
15184 struct file_name_list *next;
15186 /* Mapping of file names for this directory. */
15187 struct file_name_map *name_map;
15188 /* Non-zero if name_map is valid. */
15192 static struct file_name_list *include = NULL; /* First dir to search */
15193 static struct file_name_list *last_include = NULL; /* Last in chain */
15195 /* I/O buffer structure.
15196 The `fname' field is nonzero for source files and #include files
15197 and for the dummy text used for -D and -U.
15198 It is zero for rescanning results of macro expansion
15199 and for expanding macro arguments. */
15200 #define INPUT_STACK_MAX 400
15201 static struct file_buf {
15203 /* Filename specified with #line command. */
15204 const char *nominal_fname;
15205 /* Record where in the search path this file was found.
15206 For #include_next. */
15207 struct file_name_list *dir;
15209 ffewhereColumn column;
15210 } instack[INPUT_STACK_MAX];
15212 static int last_error_tick = 0; /* Incremented each time we print it. */
15213 static int input_file_stack_tick = 0; /* Incremented when status changes. */
15215 /* Current nesting level of input sources.
15216 `instack[indepth]' is the level currently being read. */
15217 static int indepth = -1;
15219 typedef struct file_buf FILE_BUF;
15221 /* Nonzero means -I- has been seen,
15222 so don't look for #include "foo" the source-file directory. */
15223 static int ignore_srcdir;
15225 #ifndef INCLUDE_LEN_FUDGE
15226 #define INCLUDE_LEN_FUDGE 0
15229 static void append_include_chain (struct file_name_list *first,
15230 struct file_name_list *last);
15231 static FILE *open_include_file (char *filename,
15232 struct file_name_list *searchptr);
15233 static void print_containing_files (ffebadSeverity sev);
15234 static char *read_filename_string (int ch, FILE *f);
15235 static struct file_name_map *read_name_map (const char *dirname);
15237 /* Append a chain of `struct file_name_list's
15238 to the end of the main include chain.
15239 FIRST is the beginning of the chain to append, and LAST is the end. */
15242 append_include_chain (first, last)
15243 struct file_name_list *first, *last;
15245 struct file_name_list *dir;
15247 if (!first || !last)
15253 last_include->next = first;
15255 for (dir = first; ; dir = dir->next) {
15256 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15257 if (len > max_include_len)
15258 max_include_len = len;
15264 last_include = last;
15267 /* Try to open include file FILENAME. SEARCHPTR is the directory
15268 being tried from the include file search path. This function maps
15269 filenames on file systems based on information read by
15273 open_include_file (filename, searchptr)
15275 struct file_name_list *searchptr;
15277 register struct file_name_map *map;
15278 register char *from;
15281 if (searchptr && ! searchptr->got_name_map)
15283 searchptr->name_map = read_name_map (searchptr->fname
15284 ? searchptr->fname : ".");
15285 searchptr->got_name_map = 1;
15288 /* First check the mapping for the directory we are using. */
15289 if (searchptr && searchptr->name_map)
15292 if (searchptr->fname)
15293 from += strlen (searchptr->fname) + 1;
15294 for (map = searchptr->name_map; map; map = map->map_next)
15296 if (! strcmp (map->map_from, from))
15298 /* Found a match. */
15299 return fopen (map->map_to, "r");
15304 /* Try to find a mapping file for the particular directory we are
15305 looking in. Thus #include <sys/types.h> will look up sys/types.h
15306 in /usr/include/header.gcc and look up types.h in
15307 /usr/include/sys/header.gcc. */
15308 p = strrchr (filename, '/');
15309 #ifdef DIR_SEPARATOR
15310 if (! p) p = strrchr (filename, DIR_SEPARATOR);
15312 char *tmp = strrchr (filename, DIR_SEPARATOR);
15313 if (tmp != NULL && tmp > p) p = tmp;
15319 && searchptr->fname
15320 && strlen (searchptr->fname) == (size_t) (p - filename)
15321 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15323 /* FILENAME is in SEARCHPTR, which we've already checked. */
15324 return fopen (filename, "r");
15330 map = read_name_map (".");
15334 dir = (char *) xmalloc (p - filename + 1);
15335 memcpy (dir, filename, p - filename);
15336 dir[p - filename] = '\0';
15338 map = read_name_map (dir);
15341 for (; map; map = map->map_next)
15342 if (! strcmp (map->map_from, from))
15343 return fopen (map->map_to, "r");
15345 return fopen (filename, "r");
15348 /* Print the file names and line numbers of the #include
15349 commands which led to the current file. */
15352 print_containing_files (ffebadSeverity sev)
15354 FILE_BUF *ip = NULL;
15360 /* If stack of files hasn't changed since we last printed
15361 this info, don't repeat it. */
15362 if (last_error_tick == input_file_stack_tick)
15365 for (i = indepth; i >= 0; i--)
15366 if (instack[i].fname != NULL) {
15371 /* Give up if we don't find a source file. */
15375 /* Find the other, outer source files. */
15376 for (i--; i >= 0; i--)
15377 if (instack[i].fname != NULL)
15383 str1 = "In file included";
15395 /* xgettext:no-c-format */
15396 ffebad_start_msg ("%A from %B at %0%C", sev);
15397 ffebad_here (0, ip->line, ip->column);
15398 ffebad_string (str1);
15399 ffebad_string (ip->nominal_fname);
15400 ffebad_string (str2);
15404 /* Record we have printed the status as of this time. */
15405 last_error_tick = input_file_stack_tick;
15408 /* Read a space delimited string of unlimited length from a stdio
15412 read_filename_string (ch, f)
15420 set = alloc = xmalloc (len + 1);
15421 if (! ISSPACE (ch))
15424 while ((ch = getc (f)) != EOF && ! ISSPACE (ch))
15426 if (set - alloc == len)
15429 alloc = xrealloc (alloc, len + 1);
15430 set = alloc + len / 2;
15440 /* Read the file name map file for DIRNAME. */
15442 static struct file_name_map *
15443 read_name_map (dirname)
15444 const char *dirname;
15446 /* This structure holds a linked list of file name maps, one per
15448 struct file_name_map_list
15450 struct file_name_map_list *map_list_next;
15451 char *map_list_name;
15452 struct file_name_map *map_list_map;
15454 static struct file_name_map_list *map_list;
15455 register struct file_name_map_list *map_list_ptr;
15459 int separator_needed;
15461 dirname = skip_redundant_dir_prefix (dirname);
15463 for (map_list_ptr = map_list; map_list_ptr;
15464 map_list_ptr = map_list_ptr->map_list_next)
15465 if (! strcmp (map_list_ptr->map_list_name, dirname))
15466 return map_list_ptr->map_list_map;
15468 map_list_ptr = ((struct file_name_map_list *)
15469 xmalloc (sizeof (struct file_name_map_list)));
15470 map_list_ptr->map_list_name = xstrdup (dirname);
15471 map_list_ptr->map_list_map = NULL;
15473 dirlen = strlen (dirname);
15474 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
15475 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
15476 strcpy (name, dirname);
15477 name[dirlen] = '/';
15478 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
15479 f = fopen (name, "r");
15482 map_list_ptr->map_list_map = NULL;
15487 while ((ch = getc (f)) != EOF)
15490 struct file_name_map *ptr;
15494 from = read_filename_string (ch, f);
15495 while ((ch = getc (f)) != EOF && ISSPACE (ch) && ch != '\n')
15497 to = read_filename_string (ch, f);
15499 ptr = ((struct file_name_map *)
15500 xmalloc (sizeof (struct file_name_map)));
15501 ptr->map_from = from;
15503 /* Make the real filename absolute. */
15508 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
15509 strcpy (ptr->map_to, dirname);
15510 ptr->map_to[dirlen] = '/';
15511 strcpy (ptr->map_to + dirlen + separator_needed, to);
15515 ptr->map_next = map_list_ptr->map_list_map;
15516 map_list_ptr->map_list_map = ptr;
15518 while ((ch = getc (f)) != '\n')
15525 map_list_ptr->map_list_next = map_list;
15526 map_list = map_list_ptr;
15528 return map_list_ptr->map_list_map;
15532 ffecom_file_ (const char *name)
15536 /* Do partial setup of input buffer for the sake of generating
15537 early #line directives (when -g is in effect). */
15539 fp = &instack[++indepth];
15540 memset ((char *) fp, 0, sizeof (FILE_BUF));
15543 fp->nominal_fname = fp->fname = name;
15547 ffecom_close_include_ (FILE *f)
15552 input_file_stack_tick++;
15554 ffewhere_line_kill (instack[indepth].line);
15555 ffewhere_column_kill (instack[indepth].column);
15559 ffecom_decode_include_option_ (char *spec)
15561 struct file_name_list *dirtmp;
15563 if (! ignore_srcdir && !strcmp (spec, "-"))
15567 dirtmp = (struct file_name_list *)
15568 xmalloc (sizeof (struct file_name_list));
15569 dirtmp->next = 0; /* New one goes on the end */
15570 dirtmp->fname = spec;
15571 dirtmp->got_name_map = 0;
15573 error ("directory name must immediately follow -I");
15575 append_include_chain (dirtmp, dirtmp);
15580 /* Open INCLUDEd file. */
15583 ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
15586 size_t flen = strlen (fbeg);
15587 struct file_name_list *search_start = include; /* Chain of dirs to search */
15588 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
15589 struct file_name_list *searchptr = 0;
15590 char *fname; /* Dynamically allocated fname buffer */
15597 dsp[0].fname = NULL;
15599 /* If -I- was specified, don't search current dir, only spec'd ones. */
15600 if (!ignore_srcdir)
15602 for (fp = &instack[indepth]; fp >= instack; fp--)
15608 if ((nam = fp->nominal_fname) != NULL)
15610 /* Found a named file. Figure out dir of the file,
15611 and put it in front of the search list. */
15612 dsp[0].next = search_start;
15613 search_start = dsp;
15615 ep = strrchr (nam, '/');
15616 #ifdef DIR_SEPARATOR
15617 if (ep == NULL) ep = strrchr (nam, DIR_SEPARATOR);
15619 char *tmp = strrchr (nam, DIR_SEPARATOR);
15620 if (tmp != NULL && tmp > ep) ep = tmp;
15624 ep = strrchr (nam, ']');
15625 if (ep == NULL) ep = strrchr (nam, '>');
15626 if (ep == NULL) ep = strrchr (nam, ':');
15627 if (ep != NULL) ep++;
15632 dsp[0].fname = (char *) xmalloc (n + 1);
15633 strncpy (dsp[0].fname, nam, n);
15634 dsp[0].fname[n] = '\0';
15635 if (n + INCLUDE_LEN_FUDGE > max_include_len)
15636 max_include_len = n + INCLUDE_LEN_FUDGE;
15639 dsp[0].fname = NULL; /* Current directory */
15640 dsp[0].got_name_map = 0;
15646 /* Allocate this permanently, because it gets stored in the definitions
15648 fname = xmalloc (max_include_len + flen + 4);
15649 /* + 2 above for slash and terminating null. */
15650 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
15653 /* If specified file name is absolute, just open it. */
15656 #ifdef DIR_SEPARATOR
15657 || *fbeg == DIR_SEPARATOR
15661 strncpy (fname, (char *) fbeg, flen);
15663 f = open_include_file (fname, NULL);
15669 /* Search directory path, trying to open the file.
15670 Copy each filename tried into FNAME. */
15672 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
15674 if (searchptr->fname)
15676 /* The empty string in a search path is ignored.
15677 This makes it possible to turn off entirely
15678 a standard piece of the list. */
15679 if (searchptr->fname[0] == 0)
15681 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
15682 if (fname[0] && fname[strlen (fname) - 1] != '/')
15683 strcat (fname, "/");
15684 fname[strlen (fname) + flen] = 0;
15689 strncat (fname, fbeg, flen);
15691 /* Change this 1/2 Unix 1/2 VMS file specification into a
15692 full VMS file specification */
15693 if (searchptr->fname && (searchptr->fname[0] != 0))
15695 /* Fix up the filename */
15696 hack_vms_include_specification (fname);
15700 /* This is a normal VMS filespec, so use it unchanged. */
15701 strncpy (fname, (char *) fbeg, flen);
15703 #if 0 /* Not for g77. */
15704 /* if it's '#include filename', add the missing .h */
15705 if (strchr (fname, '.') == NULL)
15706 strcat (fname, ".h");
15710 f = open_include_file (fname, searchptr);
15712 if (f == NULL && errno == EACCES)
15714 print_containing_files (FFEBAD_severityWARNING);
15715 /* xgettext:no-c-format */
15716 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
15717 FFEBAD_severityWARNING);
15718 ffebad_string (fname);
15719 ffebad_here (0, l, c);
15730 /* A file that was not found. */
15732 strncpy (fname, (char *) fbeg, flen);
15734 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
15735 ffebad_start (FFEBAD_OPEN_INCLUDE);
15736 ffebad_here (0, l, c);
15737 ffebad_string (fname);
15741 if (dsp[0].fname != NULL)
15742 free (dsp[0].fname);
15747 if (indepth >= (INPUT_STACK_MAX - 1))
15749 print_containing_files (FFEBAD_severityFATAL);
15750 /* xgettext:no-c-format */
15751 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
15752 FFEBAD_severityFATAL);
15753 ffebad_string (fname);
15754 ffebad_here (0, l, c);
15759 instack[indepth].line = ffewhere_line_use (l);
15760 instack[indepth].column = ffewhere_column_use (c);
15762 fp = &instack[indepth + 1];
15763 memset ((char *) fp, 0, sizeof (FILE_BUF));
15764 fp->nominal_fname = fp->fname = fname;
15765 fp->dir = searchptr;
15768 input_file_stack_tick++;
15773 /**INDENT* (Do not reformat this comment even with -fca option.)
15774 Data-gathering files: Given the source file listed below, compiled with
15775 f2c I obtained the output file listed after that, and from the output
15776 file I derived the above code.
15778 -------- (begin input file to f2c)
15784 double precision D1,D2
15786 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
15813 c FFEINTRIN_impACOS
15814 call fooR(ACOS(R1))
15815 c FFEINTRIN_impAIMAG
15816 call fooR(AIMAG(C1))
15817 c FFEINTRIN_impAINT
15818 call fooR(AINT(R1))
15819 c FFEINTRIN_impALOG
15820 call fooR(ALOG(R1))
15821 c FFEINTRIN_impALOG10
15822 call fooR(ALOG10(R1))
15823 c FFEINTRIN_impAMAX0
15824 call fooR(AMAX0(I1,I2))
15825 c FFEINTRIN_impAMAX1
15826 call fooR(AMAX1(R1,R2))
15827 c FFEINTRIN_impAMIN0
15828 call fooR(AMIN0(I1,I2))
15829 c FFEINTRIN_impAMIN1
15830 call fooR(AMIN1(R1,R2))
15831 c FFEINTRIN_impAMOD
15832 call fooR(AMOD(R1,R2))
15833 c FFEINTRIN_impANINT
15834 call fooR(ANINT(R1))
15835 c FFEINTRIN_impASIN
15836 call fooR(ASIN(R1))
15837 c FFEINTRIN_impATAN
15838 call fooR(ATAN(R1))
15839 c FFEINTRIN_impATAN2
15840 call fooR(ATAN2(R1,R2))
15841 c FFEINTRIN_impCABS
15842 call fooR(CABS(C1))
15843 c FFEINTRIN_impCCOS
15844 call fooC(CCOS(C1))
15845 c FFEINTRIN_impCEXP
15846 call fooC(CEXP(C1))
15847 c FFEINTRIN_impCHAR
15848 call fooA(CHAR(I1))
15849 c FFEINTRIN_impCLOG
15850 call fooC(CLOG(C1))
15851 c FFEINTRIN_impCONJG
15852 call fooC(CONJG(C1))
15855 c FFEINTRIN_impCOSH
15856 call fooR(COSH(R1))
15857 c FFEINTRIN_impCSIN
15858 call fooC(CSIN(C1))
15859 c FFEINTRIN_impCSQRT
15860 call fooC(CSQRT(C1))
15861 c FFEINTRIN_impDABS
15862 call fooD(DABS(D1))
15863 c FFEINTRIN_impDACOS
15864 call fooD(DACOS(D1))
15865 c FFEINTRIN_impDASIN
15866 call fooD(DASIN(D1))
15867 c FFEINTRIN_impDATAN
15868 call fooD(DATAN(D1))
15869 c FFEINTRIN_impDATAN2
15870 call fooD(DATAN2(D1,D2))
15871 c FFEINTRIN_impDCOS
15872 call fooD(DCOS(D1))
15873 c FFEINTRIN_impDCOSH
15874 call fooD(DCOSH(D1))
15875 c FFEINTRIN_impDDIM
15876 call fooD(DDIM(D1,D2))
15877 c FFEINTRIN_impDEXP
15878 call fooD(DEXP(D1))
15880 call fooR(DIM(R1,R2))
15881 c FFEINTRIN_impDINT
15882 call fooD(DINT(D1))
15883 c FFEINTRIN_impDLOG
15884 call fooD(DLOG(D1))
15885 c FFEINTRIN_impDLOG10
15886 call fooD(DLOG10(D1))
15887 c FFEINTRIN_impDMAX1
15888 call fooD(DMAX1(D1,D2))
15889 c FFEINTRIN_impDMIN1
15890 call fooD(DMIN1(D1,D2))
15891 c FFEINTRIN_impDMOD
15892 call fooD(DMOD(D1,D2))
15893 c FFEINTRIN_impDNINT
15894 call fooD(DNINT(D1))
15895 c FFEINTRIN_impDPROD
15896 call fooD(DPROD(R1,R2))
15897 c FFEINTRIN_impDSIGN
15898 call fooD(DSIGN(D1,D2))
15899 c FFEINTRIN_impDSIN
15900 call fooD(DSIN(D1))
15901 c FFEINTRIN_impDSINH
15902 call fooD(DSINH(D1))
15903 c FFEINTRIN_impDSQRT
15904 call fooD(DSQRT(D1))
15905 c FFEINTRIN_impDTAN
15906 call fooD(DTAN(D1))
15907 c FFEINTRIN_impDTANH
15908 call fooD(DTANH(D1))
15911 c FFEINTRIN_impIABS
15912 call fooI(IABS(I1))
15913 c FFEINTRIN_impICHAR
15914 call fooI(ICHAR(A1))
15915 c FFEINTRIN_impIDIM
15916 call fooI(IDIM(I1,I2))
15917 c FFEINTRIN_impIDNINT
15918 call fooI(IDNINT(D1))
15919 c FFEINTRIN_impINDEX
15920 call fooI(INDEX(A1,A2))
15921 c FFEINTRIN_impISIGN
15922 call fooI(ISIGN(I1,I2))
15926 call fooL(LGE(A1,A2))
15928 call fooL(LGT(A1,A2))
15930 call fooL(LLE(A1,A2))
15932 call fooL(LLT(A1,A2))
15933 c FFEINTRIN_impMAX0
15934 call fooI(MAX0(I1,I2))
15935 c FFEINTRIN_impMAX1
15936 call fooI(MAX1(R1,R2))
15937 c FFEINTRIN_impMIN0
15938 call fooI(MIN0(I1,I2))
15939 c FFEINTRIN_impMIN1
15940 call fooI(MIN1(R1,R2))
15942 call fooI(MOD(I1,I2))
15943 c FFEINTRIN_impNINT
15944 call fooI(NINT(R1))
15945 c FFEINTRIN_impSIGN
15946 call fooR(SIGN(R1,R2))
15949 c FFEINTRIN_impSINH
15950 call fooR(SINH(R1))
15951 c FFEINTRIN_impSQRT
15952 call fooR(SQRT(R1))
15955 c FFEINTRIN_impTANH
15956 call fooR(TANH(R1))
15957 c FFEINTRIN_imp_CMPLX_C
15958 call fooC(cmplx(C1,C2))
15959 c FFEINTRIN_imp_CMPLX_D
15960 call fooZ(cmplx(D1,D2))
15961 c FFEINTRIN_imp_CMPLX_I
15962 call fooC(cmplx(I1,I2))
15963 c FFEINTRIN_imp_CMPLX_R
15964 call fooC(cmplx(R1,R2))
15965 c FFEINTRIN_imp_DBLE_C
15966 call fooD(dble(C1))
15967 c FFEINTRIN_imp_DBLE_D
15968 call fooD(dble(D1))
15969 c FFEINTRIN_imp_DBLE_I
15970 call fooD(dble(I1))
15971 c FFEINTRIN_imp_DBLE_R
15972 call fooD(dble(R1))
15973 c FFEINTRIN_imp_INT_C
15975 c FFEINTRIN_imp_INT_D
15977 c FFEINTRIN_imp_INT_I
15979 c FFEINTRIN_imp_INT_R
15981 c FFEINTRIN_imp_REAL_C
15982 call fooR(real(C1))
15983 c FFEINTRIN_imp_REAL_D
15984 call fooR(real(D1))
15985 c FFEINTRIN_imp_REAL_I
15986 call fooR(real(I1))
15987 c FFEINTRIN_imp_REAL_R
15988 call fooR(real(R1))
15990 c FFEINTRIN_imp_INT_D:
15992 c FFEINTRIN_specIDINT
15993 call fooI(IDINT(D1))
15995 c FFEINTRIN_imp_INT_R:
15997 c FFEINTRIN_specIFIX
15998 call fooI(IFIX(R1))
15999 c FFEINTRIN_specINT
16002 c FFEINTRIN_imp_REAL_D:
16004 c FFEINTRIN_specSNGL
16005 call fooR(SNGL(D1))
16007 c FFEINTRIN_imp_REAL_I:
16009 c FFEINTRIN_specFLOAT
16010 call fooR(FLOAT(I1))
16011 c FFEINTRIN_specREAL
16012 call fooR(REAL(I1))
16015 -------- (end input file to f2c)
16017 -------- (begin output from providing above input file as input to:
16018 -------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
16019 -------- -e "s:^#.*$::g"')
16021 // -- translated by f2c (version 19950223).
16022 You must link the resulting object file with the libraries:
16023 -lf2c -lm (in that order)
16027 // f2c.h -- Standard Fortran to C header file //
16029 /// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
16031 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
16036 // F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
16037 // we assume short, float are OK //
16038 typedef long int // long int // integer;
16039 typedef char *address;
16040 typedef short int shortint;
16041 typedef float real;
16042 typedef double doublereal;
16043 typedef struct { real r, i; } complex;
16044 typedef struct { doublereal r, i; } doublecomplex;
16045 typedef long int // long int // logical;
16046 typedef short int shortlogical;
16047 typedef char logical1;
16048 typedef char integer1;
16049 // typedef long long longint; // // system-dependent //
16054 // Extern is for use with -E //
16068 typedef long int // int or long int // flag;
16069 typedef long int // int or long int // ftnlen;
16070 typedef long int // int or long int // ftnint;
16073 //external read, write//
16082 //internal read, write//
16112 //rewind, backspace, endfile//
16124 ftnint *inex; //parameters in standard's order//
16150 union Multitype { // for multiple entry points //
16161 typedef union Multitype Multitype;
16163 typedef long Long; // No longer used; formerly in Namelist //
16165 struct Vardesc { // for Namelist //
16171 typedef struct Vardesc Vardesc;
16178 typedef struct Namelist Namelist;
16187 // procedure parameter types for -A and -C++ //
16192 typedef int // Unknown procedure type // (*U_fp)();
16193 typedef shortint (*J_fp)();
16194 typedef integer (*I_fp)();
16195 typedef real (*R_fp)();
16196 typedef doublereal (*D_fp)(), (*E_fp)();
16197 typedef // Complex // void (*C_fp)();
16198 typedef // Double Complex // void (*Z_fp)();
16199 typedef logical (*L_fp)();
16200 typedef shortlogical (*K_fp)();
16201 typedef // Character // void (*H_fp)();
16202 typedef // Subroutine // int (*S_fp)();
16204 // E_fp is for real functions when -R is not specified //
16205 typedef void C_f; // complex function //
16206 typedef void H_f; // character function //
16207 typedef void Z_f; // double complex function //
16208 typedef doublereal E_f; // real function with -R not specified //
16210 // undef any lower-case symbols that your C compiler predefines, e.g.: //
16213 // (No such symbols should be defined in a strict ANSI C compiler.
16214 We can avoid trouble with f2c-translated code by using
16239 // Main program // MAIN__()
16241 // System generated locals //
16244 doublereal d__1, d__2;
16246 doublecomplex z__1, z__2, z__3;
16250 // Builtin functions //
16253 double pow_ri(), pow_di();
16257 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16258 asin(), atan(), atan2(), c_abs();
16259 void c_cos(), c_exp(), c_log(), r_cnjg();
16260 double cos(), cosh();
16261 void c_sin(), c_sqrt();
16262 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16263 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16264 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16265 logical l_ge(), l_gt(), l_le(), l_lt();
16269 // Local variables //
16270 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16271 fool_(), fooz_(), getem_();
16272 static char a1[10], a2[10];
16273 static complex c1, c2;
16274 static doublereal d1, d2;
16275 static integer i1, i2;
16276 static real r1, r2;
16279 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16287 d__1 = (doublereal) i1;
16288 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16298 c_div(&q__1, &c1, &c2);
16300 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16302 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16305 i__1 = pow_ii(&i1, &i2);
16307 r__1 = pow_ri(&r1, &i1);
16309 d__1 = pow_di(&d1, &i1);
16311 pow_ci(&q__1, &c1, &i1);
16313 d__1 = (doublereal) r1;
16314 d__2 = (doublereal) r2;
16315 r__1 = pow_dd(&d__1, &d__2);
16317 d__2 = (doublereal) r1;
16318 d__1 = pow_dd(&d__2, &d1);
16320 d__1 = pow_dd(&d1, &d2);
16322 d__2 = (doublereal) r1;
16323 d__1 = pow_dd(&d1, &d__2);
16325 z__2.r = c1.r, z__2.i = c1.i;
16326 z__3.r = c2.r, z__3.i = c2.i;
16327 pow_zz(&z__1, &z__2, &z__3);
16328 q__1.r = z__1.r, q__1.i = z__1.i;
16330 z__2.r = c1.r, z__2.i = c1.i;
16331 z__3.r = r1, z__3.i = 0.;
16332 pow_zz(&z__1, &z__2, &z__3);
16333 q__1.r = z__1.r, q__1.i = z__1.i;
16335 z__2.r = c1.r, z__2.i = c1.i;
16336 z__3.r = d1, z__3.i = 0.;
16337 pow_zz(&z__1, &z__2, &z__3);
16339 // FFEINTRIN_impABS //
16340 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
16342 // FFEINTRIN_impACOS //
16345 // FFEINTRIN_impAIMAG //
16346 r__1 = r_imag(&c1);
16348 // FFEINTRIN_impAINT //
16351 // FFEINTRIN_impALOG //
16354 // FFEINTRIN_impALOG10 //
16355 r__1 = r_lg10(&r1);
16357 // FFEINTRIN_impAMAX0 //
16358 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16360 // FFEINTRIN_impAMAX1 //
16361 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16363 // FFEINTRIN_impAMIN0 //
16364 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16366 // FFEINTRIN_impAMIN1 //
16367 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16369 // FFEINTRIN_impAMOD //
16370 r__1 = r_mod(&r1, &r2);
16372 // FFEINTRIN_impANINT //
16373 r__1 = r_nint(&r1);
16375 // FFEINTRIN_impASIN //
16378 // FFEINTRIN_impATAN //
16381 // FFEINTRIN_impATAN2 //
16382 r__1 = atan2(r1, r2);
16384 // FFEINTRIN_impCABS //
16387 // FFEINTRIN_impCCOS //
16390 // FFEINTRIN_impCEXP //
16393 // FFEINTRIN_impCHAR //
16394 *(unsigned char *)&ch__1[0] = i1;
16396 // FFEINTRIN_impCLOG //
16399 // FFEINTRIN_impCONJG //
16400 r_cnjg(&q__1, &c1);
16402 // FFEINTRIN_impCOS //
16405 // FFEINTRIN_impCOSH //
16408 // FFEINTRIN_impCSIN //
16411 // FFEINTRIN_impCSQRT //
16412 c_sqrt(&q__1, &c1);
16414 // FFEINTRIN_impDABS //
16415 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
16417 // FFEINTRIN_impDACOS //
16420 // FFEINTRIN_impDASIN //
16423 // FFEINTRIN_impDATAN //
16426 // FFEINTRIN_impDATAN2 //
16427 d__1 = atan2(d1, d2);
16429 // FFEINTRIN_impDCOS //
16432 // FFEINTRIN_impDCOSH //
16435 // FFEINTRIN_impDDIM //
16436 d__1 = d_dim(&d1, &d2);
16438 // FFEINTRIN_impDEXP //
16441 // FFEINTRIN_impDIM //
16442 r__1 = r_dim(&r1, &r2);
16444 // FFEINTRIN_impDINT //
16447 // FFEINTRIN_impDLOG //
16450 // FFEINTRIN_impDLOG10 //
16451 d__1 = d_lg10(&d1);
16453 // FFEINTRIN_impDMAX1 //
16454 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
16456 // FFEINTRIN_impDMIN1 //
16457 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
16459 // FFEINTRIN_impDMOD //
16460 d__1 = d_mod(&d1, &d2);
16462 // FFEINTRIN_impDNINT //
16463 d__1 = d_nint(&d1);
16465 // FFEINTRIN_impDPROD //
16466 d__1 = (doublereal) r1 * r2;
16468 // FFEINTRIN_impDSIGN //
16469 d__1 = d_sign(&d1, &d2);
16471 // FFEINTRIN_impDSIN //
16474 // FFEINTRIN_impDSINH //
16477 // FFEINTRIN_impDSQRT //
16480 // FFEINTRIN_impDTAN //
16483 // FFEINTRIN_impDTANH //
16486 // FFEINTRIN_impEXP //
16489 // FFEINTRIN_impIABS //
16490 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
16492 // FFEINTRIN_impICHAR //
16493 i__1 = *(unsigned char *)a1;
16495 // FFEINTRIN_impIDIM //
16496 i__1 = i_dim(&i1, &i2);
16498 // FFEINTRIN_impIDNINT //
16499 i__1 = i_dnnt(&d1);
16501 // FFEINTRIN_impINDEX //
16502 i__1 = i_indx(a1, a2, 10L, 10L);
16504 // FFEINTRIN_impISIGN //
16505 i__1 = i_sign(&i1, &i2);
16507 // FFEINTRIN_impLEN //
16508 i__1 = i_len(a1, 10L);
16510 // FFEINTRIN_impLGE //
16511 L__1 = l_ge(a1, a2, 10L, 10L);
16513 // FFEINTRIN_impLGT //
16514 L__1 = l_gt(a1, a2, 10L, 10L);
16516 // FFEINTRIN_impLLE //
16517 L__1 = l_le(a1, a2, 10L, 10L);
16519 // FFEINTRIN_impLLT //
16520 L__1 = l_lt(a1, a2, 10L, 10L);
16522 // FFEINTRIN_impMAX0 //
16523 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16525 // FFEINTRIN_impMAX1 //
16526 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16528 // FFEINTRIN_impMIN0 //
16529 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16531 // FFEINTRIN_impMIN1 //
16532 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16534 // FFEINTRIN_impMOD //
16537 // FFEINTRIN_impNINT //
16538 i__1 = i_nint(&r1);
16540 // FFEINTRIN_impSIGN //
16541 r__1 = r_sign(&r1, &r2);
16543 // FFEINTRIN_impSIN //
16546 // FFEINTRIN_impSINH //
16549 // FFEINTRIN_impSQRT //
16552 // FFEINTRIN_impTAN //
16555 // FFEINTRIN_impTANH //
16558 // FFEINTRIN_imp_CMPLX_C //
16561 q__1.r = r__1, q__1.i = r__2;
16563 // FFEINTRIN_imp_CMPLX_D //
16564 z__1.r = d1, z__1.i = d2;
16566 // FFEINTRIN_imp_CMPLX_I //
16569 q__1.r = r__1, q__1.i = r__2;
16571 // FFEINTRIN_imp_CMPLX_R //
16572 q__1.r = r1, q__1.i = r2;
16574 // FFEINTRIN_imp_DBLE_C //
16575 d__1 = (doublereal) c1.r;
16577 // FFEINTRIN_imp_DBLE_D //
16580 // FFEINTRIN_imp_DBLE_I //
16581 d__1 = (doublereal) i1;
16583 // FFEINTRIN_imp_DBLE_R //
16584 d__1 = (doublereal) r1;
16586 // FFEINTRIN_imp_INT_C //
16587 i__1 = (integer) c1.r;
16589 // FFEINTRIN_imp_INT_D //
16590 i__1 = (integer) d1;
16592 // FFEINTRIN_imp_INT_I //
16595 // FFEINTRIN_imp_INT_R //
16596 i__1 = (integer) r1;
16598 // FFEINTRIN_imp_REAL_C //
16601 // FFEINTRIN_imp_REAL_D //
16604 // FFEINTRIN_imp_REAL_I //
16607 // FFEINTRIN_imp_REAL_R //
16611 // FFEINTRIN_imp_INT_D: //
16613 // FFEINTRIN_specIDINT //
16614 i__1 = (integer) d1;
16617 // FFEINTRIN_imp_INT_R: //
16619 // FFEINTRIN_specIFIX //
16620 i__1 = (integer) r1;
16622 // FFEINTRIN_specINT //
16623 i__1 = (integer) r1;
16626 // FFEINTRIN_imp_REAL_D: //
16628 // FFEINTRIN_specSNGL //
16632 // FFEINTRIN_imp_REAL_I: //
16634 // FFEINTRIN_specFLOAT //
16637 // FFEINTRIN_specREAL //
16643 -------- (end output file from f2c)