1 /* com.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4 Contributed by James Craig Burley.
6 This file is part of GNU Fortran.
8 GNU Fortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU Fortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Fortran; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 Contains compiler-specific functions.
32 /* Understanding this module means understanding the interface between
33 the g77 front end and the gcc back end (or, perhaps, some other
34 back end). In here are the functions called by the front end proper
35 to notify whatever back end is in place about certain things, and
36 also the back-end-specific functions. It's a bear to deal with, so
37 lately I've been trying to simplify things, especially with regard
38 to the gcc-back-end-specific stuff.
40 Building expressions generally seems quite easy, but building decls
41 has been challenging and is undergoing revision. gcc has several
44 TYPE_DECL -- a type (int, float, struct, function, etc.)
45 CONST_DECL -- a constant of some type other than function
46 LABEL_DECL -- a variable or a constant?
47 PARM_DECL -- an argument to a function (a variable that is a dummy)
48 RESULT_DECL -- the return value of a function (a variable)
49 VAR_DECL -- other variable (can hold a ptr-to-function, struct, int, etc.)
50 FUNCTION_DECL -- a function (either the actual function or an extern ref)
51 FIELD_DECL -- a field in a struct or union (goes into types)
53 g77 has a set of functions that somewhat parallels the gcc front end
54 when it comes to building decls:
56 Internal Function (one we define, not just declare as extern):
57 if (is_nested) push_f_function_context ();
58 start_function (get_identifier ("function_name"), function_type,
59 is_nested, is_public);
60 // for each arg, build PARM_DECL and call push_parm_decl (decl) with it;
61 store_parm_decls (is_main_program);
62 ffecom_start_compstmt ();
63 // for stmts and decls inside function, do appropriate things;
64 ffecom_end_compstmt ();
65 finish_function (is_nested);
66 if (is_nested) pop_f_function_context ();
71 // fill in external, public, static, &c for decl, and
72 // set DECL_INITIAL to error_mark_node if going to initialize
73 // set is_top_level TRUE only if not at top level and decl
74 // must go in top level (i.e. not within current function decl context)
75 d = start_decl (decl, is_top_level);
76 init = ...; // if have initializer
77 finish_decl (d, init, is_top_level);
84 #if FFECOM_targetCURRENT == FFECOM_targetGCC
89 #include "output.h" /* Must follow tree.h so TREE_CODE is defined! */
92 #include "diagnostic.h"
93 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
95 #define FFECOM_GCC_INCLUDE 1 /* Enable -I. */
97 /* VMS-specific definitions */
100 #define O_RDONLY 0 /* Open arg for Read/Only */
101 #define O_WRONLY 1 /* Open arg for Write/Only */
102 #define read(fd,buf,size) VMS_read (fd,buf,size)
103 #define write(fd,buf,size) VMS_write (fd,buf,size)
104 #define open(fname,mode,prot) VMS_open (fname,mode,prot)
105 #define fopen(fname,mode) VMS_fopen (fname,mode)
106 #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
107 #define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
108 #define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
109 static int VMS_fstat (), VMS_stat ();
110 static char * VMS_strncat ();
111 static int VMS_read ();
112 static int VMS_write ();
113 static int VMS_open ();
114 static FILE * VMS_fopen ();
115 static FILE * VMS_freopen ();
116 static void hack_vms_include_specification ();
117 typedef struct { unsigned :16, :16, :16; } vms_ino_t;
118 #define ino_t vms_ino_t
119 #define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
122 #define FFECOM_DETERMINE_TYPES 1 /* for com.h */
139 /* Externals defined here. */
141 #if FFECOM_targetCURRENT == FFECOM_targetGCC
143 /* ~~gcc/tree.h *should* declare this, because toplev.c and dwarfout.c
146 const char * const language_string = "GNU F77";
148 /* Stream for reading from the input file. */
151 /* These definitions parallel those in c-decl.c so that code from that
152 module can be used pretty much as is. Much of these defs aren't
153 otherwise used, i.e. by g77 code per se, except some of them are used
154 to build some of them that are. The ones that are global (i.e. not
155 "static") are those that ste.c and such might use (directly
156 or by using com macros that reference them in their definitions). */
158 tree string_type_node;
160 /* The rest of these are inventions for g77, though there might be
161 similar things in the C front end. As they are found, these
162 inventions should be renamed to be canonical. Note that only
163 the ones currently required to be global are so. */
165 static tree ffecom_tree_fun_type_void;
167 tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
168 tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
169 tree ffecom_integer_one_node; /* " */
170 tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
172 /* _fun_type things are the f2c-specific versions. For -fno-f2c,
173 just use build_function_type and build_pointer_type on the
174 appropriate _tree_type array element. */
176 static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
177 static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
178 static tree ffecom_tree_subr_type;
179 static tree ffecom_tree_ptr_to_subr_type;
180 static tree ffecom_tree_blockdata_type;
182 static tree ffecom_tree_xargc_;
184 ffecomSymbol ffecom_symbol_null_
193 ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
194 ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
196 int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
197 tree ffecom_f2c_integer_type_node;
198 tree ffecom_f2c_ptr_to_integer_type_node;
199 tree ffecom_f2c_address_type_node;
200 tree ffecom_f2c_real_type_node;
201 tree ffecom_f2c_ptr_to_real_type_node;
202 tree ffecom_f2c_doublereal_type_node;
203 tree ffecom_f2c_complex_type_node;
204 tree ffecom_f2c_doublecomplex_type_node;
205 tree ffecom_f2c_longint_type_node;
206 tree ffecom_f2c_logical_type_node;
207 tree ffecom_f2c_flag_type_node;
208 tree ffecom_f2c_ftnlen_type_node;
209 tree ffecom_f2c_ftnlen_zero_node;
210 tree ffecom_f2c_ftnlen_one_node;
211 tree ffecom_f2c_ftnlen_two_node;
212 tree ffecom_f2c_ptr_to_ftnlen_type_node;
213 tree ffecom_f2c_ftnint_type_node;
214 tree ffecom_f2c_ptr_to_ftnint_type_node;
215 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
217 /* Simple definitions and enumerations. */
219 #ifndef FFECOM_sizeMAXSTACKITEM
220 #define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
221 larger than this # bytes
222 off stack if possible. */
225 /* For systems that have large enough stacks, they should define
226 this to 0, and here, for ease of use later on, we just undefine
229 #if FFECOM_sizeMAXSTACKITEM == 0
230 #undef FFECOM_sizeMAXSTACKITEM
236 FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */
237 FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */
238 FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */
239 FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */
240 FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */
241 FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */
242 FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */
243 FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */
244 FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */
245 FFECOM_rttypeDOUBLE_, /* C's `double' type. */
246 FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */
247 FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */
248 FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */
249 FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */
253 /* Internal typedefs. */
255 #if FFECOM_targetCURRENT == FFECOM_targetGCC
256 typedef struct _ffecom_concat_list_ ffecomConcatList_;
257 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
259 /* Private include files. */
262 /* Internal structure definitions. */
264 #if FFECOM_targetCURRENT == FFECOM_targetGCC
265 struct _ffecom_concat_list_
270 ffetargetCharacterSize minlen;
271 ffetargetCharacterSize maxlen;
273 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
275 /* Static functions (internal). */
277 #if FFECOM_targetCURRENT == FFECOM_targetGCC
278 static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
279 static tree ffecom_widest_expr_type_ (ffebld list);
280 static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
281 tree dest_size, tree source_tree,
282 ffebld source, bool scalar_arg);
283 static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
284 tree args, tree callee_commons,
286 static tree ffecom_build_f2c_string_ (int i, const char *s);
287 static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
288 bool is_f2c_complex, tree type,
289 tree args, tree dest_tree,
290 ffebld dest, bool *dest_used,
291 tree callee_commons, bool scalar_args, tree hook);
292 static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
293 bool is_f2c_complex, tree type,
294 ffebld left, ffebld right,
295 tree dest_tree, ffebld dest,
296 bool *dest_used, tree callee_commons,
297 bool scalar_args, bool ref, tree hook);
298 static void ffecom_char_args_x_ (tree *xitem, tree *length,
299 ffebld expr, bool with_null);
300 static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
301 static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
302 static ffecomConcatList_
303 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
305 ffetargetCharacterSize max);
306 static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
307 static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
308 ffetargetCharacterSize max);
309 static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
310 ffesymbol member, tree member_type,
311 ffetargetOffset offset);
312 static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
313 static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
314 bool *dest_used, bool assignp, bool widenp);
315 static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
316 ffebld dest, bool *dest_used);
317 static tree ffecom_expr_power_integer_ (ffebld expr);
318 static void ffecom_expr_transform_ (ffebld expr);
319 static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
320 static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
322 static ffeglobal ffecom_finish_global_ (ffeglobal global);
323 static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
324 static tree ffecom_get_appended_identifier_ (char us, const char *text);
325 static tree ffecom_get_external_identifier_ (ffesymbol s);
326 static tree ffecom_get_identifier_ (const char *text);
327 static tree ffecom_gen_sfuncdef_ (ffesymbol s,
330 static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
331 static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
332 static tree ffecom_init_zero_ (tree decl);
333 static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
335 static tree ffecom_intrinsic_len_ (ffebld expr);
336 static void ffecom_let_char_ (tree dest_tree,
338 ffetargetCharacterSize dest_size,
340 static void ffecom_make_gfrt_ (ffecomGfrt ix);
341 static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
342 static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
343 static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
345 static void ffecom_push_dummy_decls_ (ffebld dumlist,
347 static void ffecom_start_progunit_ (void);
348 static ffesymbol ffecom_sym_transform_ (ffesymbol s);
349 static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
350 static void ffecom_transform_common_ (ffesymbol s);
351 static void ffecom_transform_equiv_ (ffestorag st);
352 static tree ffecom_transform_namelist_ (ffesymbol s);
353 static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
355 static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
356 tree *size, tree tree);
357 static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
358 tree dest_tree, ffebld dest,
359 bool *dest_used, tree hook);
360 static tree ffecom_type_localvar_ (ffesymbol s,
363 static tree ffecom_type_namelist_ (void);
364 static tree ffecom_type_vardesc_ (void);
365 static tree ffecom_vardesc_ (ffebld expr);
366 static tree ffecom_vardesc_array_ (ffesymbol s);
367 static tree ffecom_vardesc_dims_ (ffesymbol s);
368 static tree ffecom_convert_narrow_ (tree type, tree expr);
369 static tree ffecom_convert_widen_ (tree type, tree expr);
370 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
372 /* These are static functions that parallel those found in the C front
373 end and thus have the same names. */
375 #if FFECOM_targetCURRENT == FFECOM_targetGCC
376 static tree bison_rule_compstmt_ (void);
377 static void bison_rule_pushlevel_ (void);
378 static void delete_block (tree block);
379 static int duplicate_decls (tree newdecl, tree olddecl);
380 static void finish_decl (tree decl, tree init, bool is_top_level);
381 static void finish_function (int nested);
382 static const char *lang_printable_name (tree decl, int v);
383 static tree lookup_name_current_level (tree name);
384 static struct binding_level *make_binding_level (void);
385 static void pop_f_function_context (void);
386 static void push_f_function_context (void);
387 static void push_parm_decl (tree parm);
388 static tree pushdecl_top_level (tree decl);
389 static int kept_level_p (void);
390 static tree storedecls (tree decls);
391 static void store_parm_decls (int is_main_program);
392 static tree start_decl (tree decl, bool is_top_level);
393 static void start_function (tree name, tree type, int nested, int public);
394 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
395 #if FFECOM_GCC_INCLUDE
396 static void ffecom_file_ (const char *name);
397 static void ffecom_initialize_char_syntax_ (void);
398 static void ffecom_close_include_ (FILE *f);
399 static int ffecom_decode_include_option_ (char *spec);
400 static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
402 #endif /* FFECOM_GCC_INCLUDE */
404 /* Static objects accessed by functions in this module. */
406 static ffesymbol ffecom_primary_entry_ = NULL;
407 static ffesymbol ffecom_nested_entry_ = NULL;
408 static ffeinfoKind ffecom_primary_entry_kind_;
409 static bool ffecom_primary_entry_is_proc_;
410 #if FFECOM_targetCURRENT == FFECOM_targetGCC
411 static tree ffecom_outer_function_decl_;
412 static tree ffecom_previous_function_decl_;
413 static tree ffecom_which_entrypoint_decl_;
414 static tree ffecom_float_zero_ = NULL_TREE;
415 static tree ffecom_float_half_ = NULL_TREE;
416 static tree ffecom_double_zero_ = NULL_TREE;
417 static tree ffecom_double_half_ = NULL_TREE;
418 static tree ffecom_func_result_;/* For functions. */
419 static tree ffecom_func_length_;/* For CHARACTER fns. */
420 static ffebld ffecom_list_blockdata_;
421 static ffebld ffecom_list_common_;
422 static ffebld ffecom_master_arglist_;
423 static ffeinfoBasictype ffecom_master_bt_;
424 static ffeinfoKindtype ffecom_master_kt_;
425 static ffetargetCharacterSize ffecom_master_size_;
426 static int ffecom_num_fns_ = 0;
427 static int ffecom_num_entrypoints_ = 0;
428 static bool ffecom_is_altreturning_ = FALSE;
429 static tree ffecom_multi_type_node_;
430 static tree ffecom_multi_retval_;
432 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
433 static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
434 static bool ffecom_doing_entry_ = FALSE;
435 static bool ffecom_transform_only_dummies_ = FALSE;
436 static int ffecom_typesize_pointer_;
437 static int ffecom_typesize_integer1_;
439 /* Holds pointer-to-function expressions. */
441 static tree ffecom_gfrt_[FFECOM_gfrt]
444 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NULL_TREE,
445 #include "com-rt.def"
449 /* Holds the external names of the functions. */
451 static const char *ffecom_gfrt_name_[FFECOM_gfrt]
454 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NAME,
455 #include "com-rt.def"
459 /* Whether the function returns. */
461 static bool ffecom_gfrt_volatile_[FFECOM_gfrt]
464 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) VOLATILE,
465 #include "com-rt.def"
469 /* Whether the function returns type complex. */
471 static bool ffecom_gfrt_complex_[FFECOM_gfrt]
474 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) COMPLEX,
475 #include "com-rt.def"
479 /* Whether the function is const
480 (i.e., has no side effects and only depends on its arguments). */
482 static bool ffecom_gfrt_const_[FFECOM_gfrt]
485 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) CONST,
486 #include "com-rt.def"
490 /* Type code for the function return value. */
492 static ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
495 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) TYPE,
496 #include "com-rt.def"
500 /* String of codes for the function's arguments. */
502 static const char *ffecom_gfrt_argstring_[FFECOM_gfrt]
505 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) ARGS,
506 #include "com-rt.def"
509 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
511 /* Internal macros. */
513 #if FFECOM_targetCURRENT == FFECOM_targetGCC
515 /* We let tm.h override the types used here, to handle trivial differences
516 such as the choice of unsigned int or long unsigned int for size_t.
517 When machines start needing nontrivial differences in the size type,
518 it would be best to do something here to figure out automatically
519 from other information what type to use. */
522 #define SIZE_TYPE "long unsigned int"
525 #define ffecom_concat_list_count_(catlist) ((catlist).count)
526 #define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
527 #define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
528 #define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
530 #define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
531 #define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
533 /* For each binding contour we allocate a binding_level structure
534 * which records the names defined in that contour.
537 * 1) one for each function definition,
538 * where internal declarations of the parameters appear.
540 * The current meaning of a name can be found by searching the levels from
541 * the current one out to the global one.
544 /* Note that the information in the `names' component of the global contour
545 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
549 /* A chain of _DECL nodes for all variables, constants, functions,
550 and typedef types. These are in the reverse of the order supplied.
554 /* For each level (except not the global one),
555 a chain of BLOCK nodes for all the levels
556 that were entered and exited one level down. */
559 /* The BLOCK node for this level, if one has been preallocated.
560 If 0, the BLOCK is allocated (if needed) when the level is popped. */
563 /* The binding level which this one is contained in (inherits from). */
564 struct binding_level *level_chain;
566 /* 0: no ffecom_prepare_* functions called at this level yet;
567 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
568 2: ffecom_prepare_end called. */
572 #define NULL_BINDING_LEVEL (struct binding_level *) NULL
574 /* The binding level currently in effect. */
576 static struct binding_level *current_binding_level;
578 /* A chain of binding_level structures awaiting reuse. */
580 static struct binding_level *free_binding_level;
582 /* The outermost binding level, for names of file scope.
583 This is created when the compiler is started and exists
584 through the entire run. */
586 static struct binding_level *global_binding_level;
588 /* Binding level structures are initialized by copying this one. */
590 static struct binding_level clear_binding_level
592 {NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
594 /* Language-dependent contents of an identifier. */
596 struct lang_identifier
598 struct tree_identifier ignore;
599 tree global_value, local_value, label_value;
603 /* Macros for access to language-specific slots in an identifier. */
604 /* Each of these slots contains a DECL node or null. */
606 /* This represents the value which the identifier has in the
607 file-scope namespace. */
608 #define IDENTIFIER_GLOBAL_VALUE(NODE) \
609 (((struct lang_identifier *)(NODE))->global_value)
610 /* This represents the value which the identifier has in the current
612 #define IDENTIFIER_LOCAL_VALUE(NODE) \
613 (((struct lang_identifier *)(NODE))->local_value)
614 /* This represents the value which the identifier has as a label in
615 the current label scope. */
616 #define IDENTIFIER_LABEL_VALUE(NODE) \
617 (((struct lang_identifier *)(NODE))->label_value)
618 /* This is nonzero if the identifier was "made up" by g77 code. */
619 #define IDENTIFIER_INVENTED(NODE) \
620 (((struct lang_identifier *)(NODE))->invented)
622 /* In identifiers, C uses the following fields in a special way:
623 TREE_PUBLIC to record that there was a previous local extern decl.
624 TREE_USED to record that such a decl was used.
625 TREE_ADDRESSABLE to record that the address of such a decl was used. */
627 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
628 that have names. Here so we can clear out their names' definitions
629 at the end of the function. */
631 static tree named_labels;
633 /* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
635 static tree shadowed_labels;
637 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
639 /* Return the subscript expression, modified to do range-checking.
641 `array' is the array to be checked against.
642 `element' is the subscript expression to check.
643 `dim' is the dimension number (starting at 0).
644 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
648 ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
649 const char *array_name)
651 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
652 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
657 if (element == error_mark_node)
660 if (TREE_TYPE (low) != TREE_TYPE (element))
662 if (TYPE_PRECISION (TREE_TYPE (low))
663 > TYPE_PRECISION (TREE_TYPE (element)))
664 element = convert (TREE_TYPE (low), element);
667 low = convert (TREE_TYPE (element), low);
669 high = convert (TREE_TYPE (element), high);
673 element = ffecom_save_tree (element);
674 cond = ffecom_2 (LE_EXPR, integer_type_node,
679 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
681 ffecom_2 (LE_EXPR, integer_type_node,
698 var = concat (array_name, "[", (dim ? "end" : "start"),
699 "-substring]", NULL);
700 len = strlen (var) + 1;
701 arg1 = build_string (len, var);
706 len = strlen (array_name) + 1;
707 arg1 = build_string (len, array_name);
711 var = xmalloc (strlen (array_name) + 40);
712 sprintf (var, "%s[subscript-%d-of-%d]",
714 dim + 1, total_dims);
715 len = strlen (var) + 1;
716 arg1 = build_string (len, var);
722 = build_type_variant (build_array_type (char_type_node,
726 build_int_2 (len, 0))),
728 TREE_CONSTANT (arg1) = 1;
729 TREE_STATIC (arg1) = 1;
730 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
733 /* s_rnge adds one to the element to print it, so bias against
734 that -- want to print a faithful *subscript* value. */
735 arg2 = convert (ffecom_f2c_ftnint_type_node,
736 ffecom_2 (MINUS_EXPR,
739 convert (TREE_TYPE (element),
742 proc = concat (input_filename, "/",
743 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
745 len = strlen (proc) + 1;
746 arg3 = build_string (len, proc);
751 = build_type_variant (build_array_type (char_type_node,
755 build_int_2 (len, 0))),
757 TREE_CONSTANT (arg3) = 1;
758 TREE_STATIC (arg3) = 1;
759 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
762 arg4 = convert (ffecom_f2c_ftnint_type_node,
763 build_int_2 (lineno, 0));
765 arg1 = build_tree_list (NULL_TREE, arg1);
766 arg2 = build_tree_list (NULL_TREE, arg2);
767 arg3 = build_tree_list (NULL_TREE, arg3);
768 arg4 = build_tree_list (NULL_TREE, arg4);
769 TREE_CHAIN (arg3) = arg4;
770 TREE_CHAIN (arg2) = arg3;
771 TREE_CHAIN (arg1) = arg2;
775 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
777 TREE_SIDE_EFFECTS (die) = 1;
779 element = ffecom_3 (COND_EXPR,
788 /* Return the computed element of an array reference.
790 `item' is NULL_TREE, or the transformed pointer to the array.
791 `expr' is the original opARRAYREF expression, which is transformed
792 if `item' is NULL_TREE.
793 `want_ptr' is non-zero if a pointer to the element, instead of
794 the element itself, is to be returned. */
797 ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
799 ffebld dims[FFECOM_dimensionsMAX];
802 int flatten = ffe_is_flatten_arrays ();
808 const char *array_name;
812 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
813 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
815 array_name = "[expr?]";
817 /* Build up ARRAY_REFs in reverse order (since we're column major
818 here in Fortran land). */
820 for (i = 0, list = ffebld_right (expr);
822 ++i, list = ffebld_trail (list))
824 dims[i] = ffebld_head (list);
825 type = ffeinfo_type (ffebld_basictype (dims[i]),
826 ffebld_kindtype (dims[i]));
828 && ffecom_typesize_pointer_ > ffecom_typesize_integer1_
829 && ffetype_size (type) > ffecom_typesize_integer1_)
830 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
831 pointers and 32-bit integers. Do the full 64-bit pointer
832 arithmetic, for codes using arrays for nonstandard heap-like
839 need_ptr = want_ptr || flatten;
844 item = ffecom_ptr_to_expr (ffebld_left (expr));
846 item = ffecom_expr (ffebld_left (expr));
848 if (item == error_mark_node)
851 if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
852 && ! mark_addressable (item))
853 return error_mark_node;
856 if (item == error_mark_node)
863 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
865 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
867 min = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
868 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
869 if (flag_bounds_check)
870 element = ffecom_subscript_check_ (array, element, i, total_dims,
872 if (element == error_mark_node)
875 /* Widen integral arithmetic as desired while preserving
877 tree_type = TREE_TYPE (element);
878 tree_type_x = tree_type;
880 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
881 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
882 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
884 if (TREE_TYPE (min) != tree_type_x)
885 min = convert (tree_type_x, min);
886 if (TREE_TYPE (element) != tree_type_x)
887 element = convert (tree_type_x, element);
889 item = ffecom_2 (PLUS_EXPR,
890 build_pointer_type (TREE_TYPE (array)),
892 size_binop (MULT_EXPR,
893 size_in_bytes (TREE_TYPE (array)),
895 fold (build (MINUS_EXPR,
901 item = ffecom_1 (INDIRECT_REF,
902 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
912 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
914 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
915 if (flag_bounds_check)
916 element = ffecom_subscript_check_ (array, element, i, total_dims,
918 if (element == error_mark_node)
921 /* Widen integral arithmetic as desired while preserving
923 tree_type = TREE_TYPE (element);
924 tree_type_x = tree_type;
926 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
927 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
928 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
930 element = convert (tree_type_x, element);
932 item = ffecom_2 (ARRAY_REF,
933 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
942 /* This is like gcc's stabilize_reference -- in fact, most of the code
943 comes from that -- but it handles the situation where the reference
944 is going to have its subparts picked at, and it shouldn't change
945 (or trigger extra invocations of functions in the subtrees) due to
946 this. save_expr is a bit overzealous, because we don't need the
947 entire thing calculated and saved like a temp. So, for DECLs, no
948 change is needed, because these are stable aggregates, and ARRAY_REF
949 and such might well be stable too, but for things like calculations,
950 we do need to calculate a snapshot of a value before picking at it. */
952 #if FFECOM_targetCURRENT == FFECOM_targetGCC
954 ffecom_stabilize_aggregate_ (tree ref)
957 enum tree_code code = TREE_CODE (ref);
964 /* No action is needed in this case. */
974 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
978 result = build_nt (INDIRECT_REF,
979 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
983 result = build_nt (COMPONENT_REF,
984 stabilize_reference (TREE_OPERAND (ref, 0)),
985 TREE_OPERAND (ref, 1));
989 result = build_nt (BIT_FIELD_REF,
990 stabilize_reference (TREE_OPERAND (ref, 0)),
991 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
992 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
996 result = build_nt (ARRAY_REF,
997 stabilize_reference (TREE_OPERAND (ref, 0)),
998 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
1002 result = build_nt (COMPOUND_EXPR,
1003 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
1004 stabilize_reference (TREE_OPERAND (ref, 1)));
1012 return save_expr (ref);
1015 return error_mark_node;
1018 TREE_TYPE (result) = TREE_TYPE (ref);
1019 TREE_READONLY (result) = TREE_READONLY (ref);
1020 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
1021 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
1027 /* A rip-off of gcc's convert.c convert_to_complex function,
1028 reworked to handle complex implemented as C structures
1029 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1031 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1033 ffecom_convert_to_complex_ (tree type, tree expr)
1035 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
1038 assert (TREE_CODE (type) == RECORD_TYPE);
1040 subtype = TREE_TYPE (TYPE_FIELDS (type));
1042 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
1044 expr = convert (subtype, expr);
1045 return ffecom_2 (COMPLEX_EXPR, type, expr,
1046 convert (subtype, integer_zero_node));
1049 if (form == RECORD_TYPE)
1051 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
1052 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
1056 expr = save_expr (expr);
1057 return ffecom_2 (COMPLEX_EXPR,
1060 ffecom_1 (REALPART_EXPR,
1061 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1064 ffecom_1 (IMAGPART_EXPR,
1065 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
1070 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
1071 error ("pointer value used where a complex was expected");
1073 error ("aggregate value used where a complex was expected");
1075 return ffecom_2 (COMPLEX_EXPR, type,
1076 convert (subtype, integer_zero_node),
1077 convert (subtype, integer_zero_node));
1081 /* Like gcc's convert(), but crashes if widening might happen. */
1083 #if FFECOM_targetCURRENT == FFECOM_targetGCC
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;
1154 /* Like gcc's convert(), but crashes if narrowing might happen. */
1156 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1158 ffecom_convert_widen_ (type, expr)
1161 register tree e = expr;
1162 register enum tree_code code = TREE_CODE (type);
1164 if (type == TREE_TYPE (e)
1165 || TREE_CODE (e) == ERROR_MARK)
1167 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1168 return fold (build1 (NOP_EXPR, type, e));
1169 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
1170 || code == ERROR_MARK)
1171 return error_mark_node;
1172 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
1174 assert ("void value not ignored as it ought to be" == NULL);
1175 return error_mark_node;
1177 assert (code != VOID_TYPE);
1178 if ((code != RECORD_TYPE)
1179 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
1180 assert ("narrowing COMPLEX to REAL" == NULL);
1181 assert (code != ENUMERAL_TYPE);
1182 if (code == INTEGER_TYPE)
1184 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
1185 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
1186 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1187 && (TYPE_PRECISION (type)
1188 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
1189 return fold (convert_to_integer (type, e));
1191 if (code == POINTER_TYPE)
1193 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
1194 return fold (convert_to_pointer (type, e));
1196 if (code == REAL_TYPE)
1198 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
1199 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
1200 return fold (convert_to_real (type, e));
1202 if (code == COMPLEX_TYPE)
1204 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
1205 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
1206 return fold (convert_to_complex (type, e));
1208 if (code == RECORD_TYPE)
1210 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
1211 /* Check that at least the first field name agrees. */
1212 assert (DECL_NAME (TYPE_FIELDS (type))
1213 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
1214 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1215 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
1216 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
1217 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
1219 return fold (ffecom_convert_to_complex_ (type, e));
1222 assert ("conversion to non-scalar type requested" == NULL);
1223 return error_mark_node;
1227 /* Handles making a COMPLEX type, either the standard
1228 (but buggy?) gbe way, or the safer (but less elegant?)
1231 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1233 ffecom_make_complex_type_ (tree subtype)
1239 if (ffe_is_emulate_complex ())
1241 type = make_node (RECORD_TYPE);
1242 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
1243 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
1244 TYPE_FIELDS (type) = realfield;
1249 type = make_node (COMPLEX_TYPE);
1250 TREE_TYPE (type) = subtype;
1258 /* Chooses either the gbe or the f2c way to build a
1259 complex constant. */
1261 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1263 ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
1267 if (ffe_is_emulate_complex ())
1269 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
1270 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
1271 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
1275 bothparts = build_complex (type, realpart, imagpart);
1282 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1284 ffecom_arglist_expr_ (const char *c, ffebld expr)
1287 tree *plist = &list;
1288 tree trail = NULL_TREE; /* Append char length args here. */
1289 tree *ptrail = &trail;
1294 tree wanted = NULL_TREE;
1295 static char zed[] = "0";
1300 while (expr != NULL)
1323 wanted = ffecom_f2c_complex_type_node;
1327 wanted = ffecom_f2c_doublereal_type_node;
1331 wanted = ffecom_f2c_doublecomplex_type_node;
1335 wanted = ffecom_f2c_real_type_node;
1339 wanted = ffecom_f2c_integer_type_node;
1343 wanted = ffecom_f2c_longint_type_node;
1347 assert ("bad argstring code" == NULL);
1353 exprh = ffebld_head (expr);
1357 if ((wanted == NULL_TREE)
1360 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
1361 [ffeinfo_kindtype (ffebld_info (exprh))])
1362 == TYPE_MODE (wanted))))
1364 = build_tree_list (NULL_TREE,
1365 ffecom_arg_ptr_to_expr (exprh,
1369 item = ffecom_arg_expr (exprh, &length);
1370 item = ffecom_convert_widen_ (wanted, item);
1373 item = ffecom_1 (ADDR_EXPR,
1374 build_pointer_type (TREE_TYPE (item)),
1378 = build_tree_list (NULL_TREE,
1382 plist = &TREE_CHAIN (*plist);
1383 expr = ffebld_trail (expr);
1384 if (length != NULL_TREE)
1386 *ptrail = build_tree_list (NULL_TREE, length);
1387 ptrail = &TREE_CHAIN (*ptrail);
1391 /* We've run out of args in the call; if the implementation expects
1392 more, supply null pointers for them, which the implementation can
1393 check to see if an arg was omitted. */
1395 while (*c != '\0' && *c != '0')
1400 assert ("missing arg to run-time routine!" == NULL);
1415 assert ("bad arg string code" == NULL);
1419 = build_tree_list (NULL_TREE,
1421 plist = &TREE_CHAIN (*plist);
1430 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1432 ffecom_widest_expr_type_ (ffebld list)
1435 ffebld widest = NULL;
1437 ffetype widest_type = NULL;
1440 for (; list != NULL; list = ffebld_trail (list))
1442 item = ffebld_head (list);
1445 if ((widest != NULL)
1446 && (ffeinfo_basictype (ffebld_info (item))
1447 != ffeinfo_basictype (ffebld_info (widest))))
1449 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
1450 ffeinfo_kindtype (ffebld_info (item)));
1451 if ((widest == FFEINFO_kindtypeNONE)
1452 || (ffetype_size (type)
1453 > ffetype_size (widest_type)))
1460 assert (widest != NULL);
1461 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
1462 [ffeinfo_kindtype (ffebld_info (widest))];
1463 assert (t != NULL_TREE);
1468 /* Check whether a partial overlap between two expressions is possible.
1470 Can *starting* to write a portion of expr1 change the value
1471 computed (perhaps already, *partially*) by expr2?
1473 Currently, this is a concern only for a COMPLEX expr1. But if it
1474 isn't in COMMON or local EQUIVALENCE, since we don't support
1475 aliasing of arguments, it isn't a concern. */
1478 ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2 ATTRIBUTE_UNUSED)
1483 switch (ffebld_op (expr1))
1485 case FFEBLD_opSYMTER:
1486 sym = ffebld_symter (expr1);
1489 case FFEBLD_opARRAYREF:
1490 if (ffebld_op (ffebld_left (expr1)) != FFEBLD_opSYMTER)
1492 sym = ffebld_symter (ffebld_left (expr1));
1499 if (ffesymbol_where (sym) != FFEINFO_whereCOMMON
1500 && (ffesymbol_where (sym) != FFEINFO_whereLOCAL
1501 || ! (st = ffesymbol_storage (sym))
1502 || ! ffestorag_parent (st)))
1505 /* It's in COMMON or local EQUIVALENCE. */
1510 /* Check whether dest and source might overlap. ffebld versions of these
1511 might or might not be passed, will be NULL if not.
1513 The test is really whether source_tree is modifiable and, if modified,
1514 might overlap destination such that the value(s) in the destination might
1515 change before it is finally modified. dest_* are the canonized
1516 destination itself. */
1518 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1520 ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
1521 tree source_tree, ffebld source UNUSED,
1529 if (source_tree == NULL_TREE)
1532 switch (TREE_CODE (source_tree))
1535 case IDENTIFIER_NODE:
1546 case TRUNC_DIV_EXPR:
1548 case FLOOR_DIV_EXPR:
1549 case ROUND_DIV_EXPR:
1550 case TRUNC_MOD_EXPR:
1552 case FLOOR_MOD_EXPR:
1553 case ROUND_MOD_EXPR:
1555 case EXACT_DIV_EXPR:
1556 case FIX_TRUNC_EXPR:
1558 case FIX_FLOOR_EXPR:
1559 case FIX_ROUND_EXPR:
1573 case BIT_ANDTC_EXPR:
1575 case TRUTH_ANDIF_EXPR:
1576 case TRUTH_ORIF_EXPR:
1577 case TRUTH_AND_EXPR:
1579 case TRUTH_XOR_EXPR:
1580 case TRUTH_NOT_EXPR:
1596 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1597 TREE_OPERAND (source_tree, 1), NULL,
1601 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1602 TREE_OPERAND (source_tree, 0), NULL,
1607 case NON_LVALUE_EXPR:
1609 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1612 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
1614 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1619 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1620 TREE_OPERAND (source_tree, 1), NULL,
1622 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1623 TREE_OPERAND (source_tree, 2), NULL,
1628 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
1630 TREE_OPERAND (source_tree, 0));
1634 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
1637 source_decl = source_tree;
1638 source_offset = bitsize_zero_node;
1639 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
1643 case REFERENCE_EXPR:
1644 case PREDECREMENT_EXPR:
1645 case PREINCREMENT_EXPR:
1646 case POSTDECREMENT_EXPR:
1647 case POSTINCREMENT_EXPR:
1655 /* Come here when source_decl, source_offset, and source_size filled
1656 in appropriately. */
1658 if (source_decl == NULL_TREE)
1659 return FALSE; /* No decl involved, so no overlap. */
1661 if (source_decl != dest_decl)
1662 return FALSE; /* Different decl, no overlap. */
1664 if (TREE_CODE (dest_size) == ERROR_MARK)
1665 return TRUE; /* Assignment into entire assumed-size
1666 array? Shouldn't happen.... */
1668 t = ffecom_2 (LE_EXPR, integer_type_node,
1669 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
1671 convert (TREE_TYPE (dest_offset),
1673 convert (TREE_TYPE (dest_offset),
1676 if (integer_onep (t))
1677 return FALSE; /* Destination precedes source. */
1680 || (source_size == NULL_TREE)
1681 || (TREE_CODE (source_size) == ERROR_MARK)
1682 || integer_zerop (source_size))
1683 return TRUE; /* No way to tell if dest follows source. */
1685 t = ffecom_2 (LE_EXPR, integer_type_node,
1686 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
1688 convert (TREE_TYPE (source_offset),
1690 convert (TREE_TYPE (source_offset),
1693 if (integer_onep (t))
1694 return FALSE; /* Destination follows source. */
1696 return TRUE; /* Destination and source overlap. */
1700 /* Check whether dest might overlap any of a list of arguments or is
1701 in a COMMON area the callee might know about (and thus modify). */
1703 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1705 ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
1706 tree args, tree callee_commons,
1714 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
1717 if (dest_decl == NULL_TREE)
1718 return FALSE; /* Seems unlikely! */
1720 /* If the decl cannot be determined reliably, or if its in COMMON
1721 and the callee isn't known to not futz with COMMON via other
1722 means, overlap might happen. */
1724 if ((TREE_CODE (dest_decl) == ERROR_MARK)
1725 || ((callee_commons != NULL_TREE)
1726 && TREE_PUBLIC (dest_decl)))
1729 for (; args != NULL_TREE; args = TREE_CHAIN (args))
1731 if (((arg = TREE_VALUE (args)) != NULL_TREE)
1732 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
1733 arg, NULL, scalar_args))
1741 /* Build a string for a variable name as used by NAMELIST. This means that
1742 if we're using the f2c library, we build an uppercase string, since
1745 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1747 ffecom_build_f2c_string_ (int i, const char *s)
1749 if (!ffe_is_f2c_library ())
1750 return build_string (i, s);
1759 if (((size_t) i) > ARRAY_SIZE (space))
1760 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
1764 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
1768 t = build_string (i, tmp);
1770 if (((size_t) i) > ARRAY_SIZE (space))
1771 malloc_kill_ks (malloc_pool_image (), tmp, i);
1778 /* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1779 type to just get whatever the function returns), handling the
1780 f2c value-returning convention, if required, by prepending
1781 to the arglist a pointer to a temporary to receive the return value. */
1783 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1785 ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1786 tree type, tree args, tree dest_tree,
1787 ffebld dest, bool *dest_used, tree callee_commons,
1788 bool scalar_args, tree hook)
1793 if (dest_used != NULL)
1798 if ((dest_used == NULL)
1800 || (ffeinfo_basictype (ffebld_info (dest))
1801 != FFEINFO_basictypeCOMPLEX)
1802 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
1803 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
1804 || ffecom_args_overlapping_ (dest_tree, dest, args,
1809 tempvar = ffecom_make_tempvar (ffecom_tree_type
1810 [FFEINFO_basictypeCOMPLEX][kt],
1811 FFETARGET_charactersizeNONE,
1821 tempvar = dest_tree;
1826 = build_tree_list (NULL_TREE,
1827 ffecom_1 (ADDR_EXPR,
1828 build_pointer_type (TREE_TYPE (tempvar)),
1830 TREE_CHAIN (item) = args;
1832 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1835 if (tempvar != dest_tree)
1836 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
1839 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
1842 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
1843 item = ffecom_convert_narrow_ (type, item);
1849 /* Given two arguments, transform them and make a call to the given
1850 function via ffecom_call_. */
1852 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1854 ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
1855 tree type, ffebld left, ffebld right,
1856 tree dest_tree, ffebld dest, bool *dest_used,
1857 tree callee_commons, bool scalar_args, bool ref, tree hook)
1866 /* Pass arguments by reference. */
1867 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
1868 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
1872 /* Pass arguments by value. */
1873 left_tree = ffecom_arg_expr (left, &left_length);
1874 right_tree = ffecom_arg_expr (right, &right_length);
1878 left_tree = build_tree_list (NULL_TREE, left_tree);
1879 right_tree = build_tree_list (NULL_TREE, right_tree);
1880 TREE_CHAIN (left_tree) = right_tree;
1882 if (left_length != NULL_TREE)
1884 left_length = build_tree_list (NULL_TREE, left_length);
1885 TREE_CHAIN (right_tree) = left_length;
1888 if (right_length != NULL_TREE)
1890 right_length = build_tree_list (NULL_TREE, right_length);
1891 if (left_length != NULL_TREE)
1892 TREE_CHAIN (left_length) = right_length;
1894 TREE_CHAIN (right_tree) = right_length;
1897 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
1898 dest_tree, dest, dest_used, callee_commons,
1903 /* Return ptr/length args for char subexpression
1905 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1906 subexpressions by constructing the appropriate trees for the ptr-to-
1907 character-text and length-of-character-text arguments in a calling
1910 Note that if with_null is TRUE, and the expression is an opCONTER,
1911 a null byte is appended to the string. */
1913 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1915 ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
1919 ffetargetCharacter1 val;
1920 ffetargetCharacterSize newlen;
1922 switch (ffebld_op (expr))
1924 case FFEBLD_opCONTER:
1925 val = ffebld_constant_character1 (ffebld_conter (expr));
1926 newlen = ffetarget_length_character1 (val);
1929 /* Begin FFETARGET-NULL-KLUDGE. */
1933 *length = build_int_2 (newlen, 0);
1934 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1935 high = build_int_2 (newlen, 0);
1936 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
1937 item = build_string (newlen,
1938 ffetarget_text_character1 (val));
1939 /* End FFETARGET-NULL-KLUDGE. */
1941 = build_type_variant
1945 (ffecom_f2c_ftnlen_type_node,
1946 ffecom_f2c_ftnlen_one_node,
1949 TREE_CONSTANT (item) = 1;
1950 TREE_STATIC (item) = 1;
1951 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
1955 case FFEBLD_opSYMTER:
1957 ffesymbol s = ffebld_symter (expr);
1959 item = ffesymbol_hook (s).decl_tree;
1960 if (item == NULL_TREE)
1962 s = ffecom_sym_transform_ (s);
1963 item = ffesymbol_hook (s).decl_tree;
1965 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
1967 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
1968 *length = ffesymbol_hook (s).length_tree;
1971 *length = build_int_2 (ffesymbol_size (s), 0);
1972 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
1975 else if (item == error_mark_node)
1976 *length = error_mark_node;
1978 /* FFEINFO_kindFUNCTION. */
1979 *length = NULL_TREE;
1980 if (!ffesymbol_hook (s).addr
1981 && (item != error_mark_node))
1982 item = ffecom_1 (ADDR_EXPR,
1983 build_pointer_type (TREE_TYPE (item)),
1988 case FFEBLD_opARRAYREF:
1990 ffecom_char_args_ (&item, length, ffebld_left (expr));
1992 if (item == error_mark_node || *length == error_mark_node)
1994 item = *length = error_mark_node;
1998 item = ffecom_arrayref_ (item, expr, 1);
2002 case FFEBLD_opSUBSTR:
2006 ffebld thing = ffebld_right (expr);
2009 const char *char_name;
2013 assert (ffebld_op (thing) == FFEBLD_opITEM);
2014 start = ffebld_head (thing);
2015 thing = ffebld_trail (thing);
2016 assert (ffebld_trail (thing) == NULL);
2017 end = ffebld_head (thing);
2019 /* Determine name for pretty-printing range-check errors. */
2020 for (left_symter = ffebld_left (expr);
2021 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
2022 left_symter = ffebld_left (left_symter))
2024 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
2025 char_name = ffesymbol_text (ffebld_symter (left_symter));
2027 char_name = "[expr?]";
2029 ffecom_char_args_ (&item, length, ffebld_left (expr));
2031 if (item == error_mark_node || *length == error_mark_node)
2033 item = *length = error_mark_node;
2037 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
2039 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2047 end_tree = ffecom_expr (end);
2048 if (flag_bounds_check)
2049 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2051 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2054 if (end_tree == error_mark_node)
2056 item = *length = error_mark_node;
2065 start_tree = ffecom_expr (start);
2066 if (flag_bounds_check)
2067 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
2069 start_tree = convert (ffecom_f2c_ftnlen_type_node,
2072 if (start_tree == error_mark_node)
2074 item = *length = error_mark_node;
2078 start_tree = ffecom_save_tree (start_tree);
2080 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
2082 ffecom_2 (MINUS_EXPR,
2083 TREE_TYPE (start_tree),
2085 ffecom_f2c_ftnlen_one_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,
2098 end_tree = ffecom_expr (end);
2099 if (flag_bounds_check)
2100 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
2102 end_tree = convert (ffecom_f2c_ftnlen_type_node,
2105 if (end_tree == error_mark_node)
2107 item = *length = error_mark_node;
2111 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
2112 ffecom_f2c_ftnlen_one_node,
2113 ffecom_2 (MINUS_EXPR,
2114 ffecom_f2c_ftnlen_type_node,
2115 end_tree, start_tree));
2121 case FFEBLD_opFUNCREF:
2123 ffesymbol s = ffebld_symter (ffebld_left (expr));
2126 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
2129 if (size == FFETARGET_charactersizeNONE)
2130 /* ~~Kludge alert! This should someday be fixed. */
2133 *length = build_int_2 (size, 0);
2134 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2136 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
2137 == FFEINFO_whereINTRINSIC)
2141 /* Invocation of an intrinsic returning CHARACTER*1. */
2142 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
2146 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
2147 assert (ix != FFECOM_gfrt);
2148 item = ffecom_gfrt_tree_ (ix);
2153 item = ffesymbol_hook (s).decl_tree;
2154 if (item == NULL_TREE)
2156 s = ffecom_sym_transform_ (s);
2157 item = ffesymbol_hook (s).decl_tree;
2159 if (item == error_mark_node)
2161 item = *length = error_mark_node;
2165 if (!ffesymbol_hook (s).addr)
2166 item = ffecom_1_fn (item);
2170 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
2172 tempvar = ffebld_nonter_hook (expr);
2175 tempvar = ffecom_1 (ADDR_EXPR,
2176 build_pointer_type (TREE_TYPE (tempvar)),
2179 args = build_tree_list (NULL_TREE, tempvar);
2181 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */
2182 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
2185 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
2186 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
2188 TREE_CHAIN (TREE_CHAIN (args))
2189 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
2190 ffebld_right (expr));
2194 TREE_CHAIN (TREE_CHAIN (args))
2195 = ffecom_list_ptr_to_expr (ffebld_right (expr));
2199 item = ffecom_3s (CALL_EXPR,
2200 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
2201 item, args, NULL_TREE);
2202 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
2207 case FFEBLD_opCONVERT:
2209 ffecom_char_args_ (&item, length, ffebld_left (expr));
2211 if (item == error_mark_node || *length == error_mark_node)
2213 item = *length = error_mark_node;
2217 if ((ffebld_size_known (ffebld_left (expr))
2218 == FFETARGET_charactersizeNONE)
2219 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
2220 { /* Possible blank-padding needed, copy into
2227 tempvar = ffecom_make_tempvar (char_type_node,
2228 ffebld_size (expr), -1);
2230 tempvar = ffebld_nonter_hook (expr);
2233 tempvar = ffecom_1 (ADDR_EXPR,
2234 build_pointer_type (TREE_TYPE (tempvar)),
2237 newlen = build_int_2 (ffebld_size (expr), 0);
2238 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
2240 args = build_tree_list (NULL_TREE, tempvar);
2241 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
2242 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
2243 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
2244 = build_tree_list (NULL_TREE, *length);
2246 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
2247 TREE_SIDE_EFFECTS (item) = 1;
2248 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
2253 { /* Just truncate the length. */
2254 *length = build_int_2 (ffebld_size (expr), 0);
2255 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
2260 assert ("bad op for single char arg expr" == NULL);
2269 /* Check the size of the type to be sure it doesn't overflow the
2270 "portable" capacities of the compiler back end. `dummy' types
2271 can generally overflow the normal sizes as long as the computations
2272 themselves don't overflow. A particular target of the back end
2273 must still enforce its size requirements, though, and the back
2274 end takes care of this in stor-layout.c. */
2276 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2278 ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
2280 if (TREE_CODE (type) == ERROR_MARK)
2283 if (TYPE_SIZE (type) == NULL_TREE)
2286 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2289 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
2290 || (!dummy && (((TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0))
2291 || TREE_OVERFLOW (TYPE_SIZE (type)))))
2293 ffebad_start (FFEBAD_ARRAY_LARGE);
2294 ffebad_string (ffesymbol_text (s));
2295 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
2298 return error_mark_node;
2305 /* Builds a length argument (PARM_DECL). Also wraps type in an array type
2306 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2307 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2309 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2311 ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
2313 ffetargetCharacterSize sz = ffesymbol_size (s);
2318 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
2319 tlen = NULL_TREE; /* A statement function, no length passed. */
2322 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
2323 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
2324 ffesymbol_text (s));
2326 tlen = ffecom_get_invented_identifier ("__g77_%s", "length");
2327 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
2329 DECL_ARTIFICIAL (tlen) = 1;
2333 if (sz == FFETARGET_charactersizeNONE)
2335 assert (tlen != NULL_TREE);
2336 highval = variable_size (tlen);
2340 highval = build_int_2 (sz, 0);
2341 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
2344 type = build_array_type (type,
2345 build_range_type (ffecom_f2c_ftnlen_type_node,
2346 ffecom_f2c_ftnlen_one_node,
2354 /* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2356 ffecomConcatList_ catlist;
2357 ffebld expr; // expr of CHARACTER basictype.
2358 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2359 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2361 Scans expr for character subexpressions, updates and returns catlist
2364 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2365 static ffecomConcatList_
2366 ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
2367 ffetargetCharacterSize max)
2369 ffetargetCharacterSize sz;
2371 recurse: /* :::::::::::::::::::: */
2376 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
2377 return catlist; /* Don't append any more items. */
2379 switch (ffebld_op (expr))
2381 case FFEBLD_opCONTER:
2382 case FFEBLD_opSYMTER:
2383 case FFEBLD_opARRAYREF:
2384 case FFEBLD_opFUNCREF:
2385 case FFEBLD_opSUBSTR:
2386 case FFEBLD_opCONVERT: /* Callers should strip this off beforehand
2387 if they don't need to preserve it. */
2388 if (catlist.count == catlist.max)
2389 { /* Make a (larger) list. */
2393 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
2394 newx = malloc_new_ks (malloc_pool_image (), "catlist",
2395 newmax * sizeof (newx[0]));
2396 if (catlist.max != 0)
2398 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
2399 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2400 catlist.max * sizeof (newx[0]));
2402 catlist.max = newmax;
2403 catlist.exprs = newx;
2405 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
2406 catlist.minlen += sz;
2408 ++catlist.minlen; /* Not true for F90; can be 0 length. */
2409 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
2410 catlist.maxlen = sz;
2412 catlist.maxlen += sz;
2413 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
2414 { /* This item overlaps (or is beyond) the end
2415 of the destination. */
2416 switch (ffebld_op (expr))
2418 case FFEBLD_opCONTER:
2419 case FFEBLD_opSYMTER:
2420 case FFEBLD_opARRAYREF:
2421 case FFEBLD_opFUNCREF:
2422 case FFEBLD_opSUBSTR:
2423 /* ~~Do useful truncations here. */
2427 assert ("op changed or inconsistent switches!" == NULL);
2431 catlist.exprs[catlist.count++] = expr;
2434 case FFEBLD_opPAREN:
2435 expr = ffebld_left (expr);
2436 goto recurse; /* :::::::::::::::::::: */
2438 case FFEBLD_opCONCATENATE:
2439 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
2440 expr = ffebld_right (expr);
2441 goto recurse; /* :::::::::::::::::::: */
2443 #if 0 /* Breaks passing small actual arg to larger
2444 dummy arg of sfunc */
2445 case FFEBLD_opCONVERT:
2446 expr = ffebld_left (expr);
2448 ffetargetCharacterSize cmax;
2450 cmax = catlist.len + ffebld_size_known (expr);
2452 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
2455 goto recurse; /* :::::::::::::::::::: */
2462 assert ("bad op in _gather_" == NULL);
2468 /* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2470 ffecomConcatList_ catlist;
2471 ffecom_concat_list_kill_(catlist);
2473 Anything allocated within the list info is deallocated. */
2475 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2477 ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
2479 if (catlist.max != 0)
2480 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
2481 catlist.max * sizeof (catlist.exprs[0]));
2485 /* Make list of concatenated string exprs.
2487 Returns a flattened list of concatenated subexpressions given a
2488 tree of such expressions. */
2490 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2491 static ffecomConcatList_
2492 ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
2494 ffecomConcatList_ catlist;
2496 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
2497 return ffecom_concat_list_gather_ (catlist, expr, max);
2502 /* Provide some kind of useful info on member of aggregate area,
2503 since current g77/gcc technology does not provide debug info
2504 on these members. */
2506 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2508 ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
2509 tree member_type UNUSED, ffetargetOffset offset)
2519 for (type_id = member_type;
2520 TREE_CODE (type_id) != IDENTIFIER_NODE;
2523 switch (TREE_CODE (type_id))
2527 type_id = TYPE_NAME (type_id);
2532 type_id = TREE_TYPE (type_id);
2536 assert ("no IDENTIFIER_NODE for type!" == NULL);
2537 type_id = error_mark_node;
2543 if (ffecom_transform_only_dummies_
2544 || !ffe_is_debug_kludge ())
2545 return; /* Can't do this yet, maybe later. */
2548 + strlen (aggr_type)
2549 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
2551 + IDENTIFIER_LENGTH (type_id);
2554 if (((size_t) len) >= ARRAY_SIZE (space))
2555 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
2559 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
2561 IDENTIFIER_POINTER (DECL_NAME (aggr)),
2564 value = build_string (len, buff);
2566 = build_type_variant (build_array_type (char_type_node,
2570 build_int_2 (strlen (buff), 0))),
2572 decl = build_decl (VAR_DECL,
2573 ffecom_get_identifier_ (ffesymbol_text (member)),
2575 TREE_CONSTANT (decl) = 1;
2576 TREE_STATIC (decl) = 1;
2577 DECL_INITIAL (decl) = error_mark_node;
2578 DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */
2579 decl = start_decl (decl, FALSE);
2580 finish_decl (decl, value, FALSE);
2582 if (buff != &space[0])
2583 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
2587 /* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2589 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2590 int i; // entry# for this entrypoint (used by master fn)
2591 ffecom_do_entrypoint_(s,i);
2593 Makes a public entry point that calls our private master fn (already
2596 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2598 ffecom_do_entry_ (ffesymbol fn, int entrynum)
2601 tree type; /* Type of function. */
2602 tree multi_retval; /* Var holding return value (union). */
2603 tree result; /* Var holding result. */
2604 ffeinfoBasictype bt;
2608 bool charfunc; /* All entry points return same type
2610 bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
2611 bool multi; /* Master fn has multiple return types. */
2612 bool altreturning = FALSE; /* This entry point has alternate returns. */
2613 int old_lineno = lineno;
2614 const char *old_input_filename = input_filename;
2616 input_filename = ffesymbol_where_filename (fn);
2617 lineno = ffesymbol_where_filelinenum (fn);
2619 ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
2621 switch (ffecom_primary_entry_kind_)
2623 case FFEINFO_kindFUNCTION:
2625 /* Determine actual return type for function. */
2627 gt = FFEGLOBAL_typeFUNC;
2628 bt = ffesymbol_basictype (fn);
2629 kt = ffesymbol_kindtype (fn);
2630 if (bt == FFEINFO_basictypeNONE)
2632 ffeimplic_establish_symbol (fn);
2633 if (ffesymbol_funcresult (fn) != NULL)
2634 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
2635 bt = ffesymbol_basictype (fn);
2636 kt = ffesymbol_kindtype (fn);
2639 if (bt == FFEINFO_basictypeCHARACTER)
2640 charfunc = TRUE, cmplxfunc = FALSE;
2641 else if ((bt == FFEINFO_basictypeCOMPLEX)
2642 && ffesymbol_is_f2c (fn))
2643 charfunc = FALSE, cmplxfunc = TRUE;
2645 charfunc = cmplxfunc = FALSE;
2648 type = ffecom_tree_fun_type_void;
2649 else if (ffesymbol_is_f2c (fn))
2650 type = ffecom_tree_fun_type[bt][kt];
2652 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
2654 if ((type == NULL_TREE)
2655 || (TREE_TYPE (type) == NULL_TREE))
2656 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
2658 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
2661 case FFEINFO_kindSUBROUTINE:
2662 gt = FFEGLOBAL_typeSUBR;
2663 bt = FFEINFO_basictypeNONE;
2664 kt = FFEINFO_kindtypeNONE;
2665 if (ffecom_is_altreturning_)
2666 { /* Am _I_ altreturning? */
2667 for (item = ffesymbol_dummyargs (fn);
2669 item = ffebld_trail (item))
2671 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
2673 altreturning = TRUE;
2678 type = ffecom_tree_subr_type;
2680 type = ffecom_tree_fun_type_void;
2683 type = ffecom_tree_fun_type_void;
2690 assert ("say what??" == NULL);
2692 case FFEINFO_kindANY:
2693 gt = FFEGLOBAL_typeANY;
2694 bt = FFEINFO_basictypeNONE;
2695 kt = FFEINFO_kindtypeNONE;
2696 type = error_mark_node;
2703 /* build_decl uses the current lineno and input_filename to set the decl
2704 source info. So, I've putzed with ffestd and ffeste code to update that
2705 source info to point to the appropriate statement just before calling
2706 ffecom_do_entrypoint (which calls this fn). */
2708 start_function (ffecom_get_external_identifier_ (fn),
2710 0, /* nested/inline */
2711 1); /* TREE_PUBLIC */
2713 if (((g = ffesymbol_global (fn)) != NULL)
2714 && ((ffeglobal_type (g) == gt)
2715 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
2717 ffeglobal_set_hook (g, current_function_decl);
2720 /* Reset args in master arg list so they get retransitioned. */
2722 for (item = ffecom_master_arglist_;
2724 item = ffebld_trail (item))
2729 arg = ffebld_head (item);
2730 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2731 continue; /* Alternate return or some such thing. */
2732 s = ffebld_symter (arg);
2733 ffesymbol_hook (s).decl_tree = NULL_TREE;
2734 ffesymbol_hook (s).length_tree = NULL_TREE;
2737 /* Build dummy arg list for this entry point. */
2739 if (charfunc || cmplxfunc)
2740 { /* Prepend arg for where result goes. */
2745 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
2747 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
2749 result = ffecom_get_invented_identifier ("__g77_%s", "result");
2751 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2754 length = ffecom_char_enhance_arg_ (&type, fn);
2756 length = NULL_TREE; /* Not ref'd if !charfunc. */
2758 type = build_pointer_type (type);
2759 result = build_decl (PARM_DECL, result, type);
2761 push_parm_decl (result);
2762 ffecom_func_result_ = result;
2766 push_parm_decl (length);
2767 ffecom_func_length_ = length;
2771 result = DECL_RESULT (current_function_decl);
2773 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
2775 store_parm_decls (0);
2777 ffecom_start_compstmt ();
2778 /* Disallow temp vars at this level. */
2779 current_binding_level->prep_state = 2;
2781 /* Make local var to hold return type for multi-type master fn. */
2785 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
2787 multi_retval = build_decl (VAR_DECL, multi_retval,
2788 ffecom_multi_type_node_);
2789 multi_retval = start_decl (multi_retval, FALSE);
2790 finish_decl (multi_retval, NULL_TREE, FALSE);
2793 multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */
2795 /* Here we emit the actual code for the entry point. */
2801 tree arglist = NULL_TREE;
2802 tree *plist = &arglist;
2808 /* Prepare actual arg list based on master arg list. */
2810 for (list = ffecom_master_arglist_;
2812 list = ffebld_trail (list))
2814 arg = ffebld_head (list);
2815 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2817 s = ffebld_symter (arg);
2818 if (ffesymbol_hook (s).decl_tree == NULL_TREE
2819 || ffesymbol_hook (s).decl_tree == error_mark_node)
2820 actarg = null_pointer_node; /* We don't have this arg. */
2822 actarg = ffesymbol_hook (s).decl_tree;
2823 *plist = build_tree_list (NULL_TREE, actarg);
2824 plist = &TREE_CHAIN (*plist);
2827 /* This code appends the length arguments for character
2828 variables/arrays. */
2830 for (list = ffecom_master_arglist_;
2832 list = ffebld_trail (list))
2834 arg = ffebld_head (list);
2835 if (ffebld_op (arg) != FFEBLD_opSYMTER)
2837 s = ffebld_symter (arg);
2838 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
2839 continue; /* Only looking for CHARACTER arguments. */
2840 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
2841 continue; /* Only looking for variables and arrays. */
2842 if (ffesymbol_hook (s).length_tree == NULL_TREE
2843 || ffesymbol_hook (s).length_tree == error_mark_node)
2844 actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */
2846 actarg = ffesymbol_hook (s).length_tree;
2847 *plist = build_tree_list (NULL_TREE, actarg);
2848 plist = &TREE_CHAIN (*plist);
2851 /* Prepend character-value return info to actual arg list. */
2855 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
2856 TREE_CHAIN (prepend)
2857 = build_tree_list (NULL_TREE, ffecom_func_length_);
2858 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
2862 /* Prepend multi-type return value to actual arg list. */
2867 = build_tree_list (NULL_TREE,
2868 ffecom_1 (ADDR_EXPR,
2869 build_pointer_type (TREE_TYPE (multi_retval)),
2871 TREE_CHAIN (prepend) = arglist;
2875 /* Prepend my entry-point number to the actual arg list. */
2877 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
2878 TREE_CHAIN (prepend) = arglist;
2881 /* Build the call to the master function. */
2883 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
2884 call = ffecom_3s (CALL_EXPR,
2885 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
2886 master_fn, arglist, NULL_TREE);
2888 /* Decide whether the master function is a function or subroutine, and
2889 handle the return value for my entry point. */
2891 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
2894 expand_expr_stmt (call);
2895 expand_null_return ();
2897 else if (multi && cmplxfunc)
2899 expand_expr_stmt (call);
2901 = ffecom_1 (INDIRECT_REF,
2902 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2904 result = ffecom_modify (NULL_TREE, result,
2905 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
2907 ffecom_multi_fields_[bt][kt]));
2908 expand_expr_stmt (result);
2909 expand_null_return ();
2913 expand_expr_stmt (call);
2915 = ffecom_modify (NULL_TREE, result,
2916 convert (TREE_TYPE (result),
2917 ffecom_2 (COMPONENT_REF,
2918 ffecom_tree_type[bt][kt],
2920 ffecom_multi_fields_[bt][kt])));
2921 expand_return (result);
2926 = ffecom_1 (INDIRECT_REF,
2927 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
2929 result = ffecom_modify (NULL_TREE, result, call);
2930 expand_expr_stmt (result);
2931 expand_null_return ();
2935 result = ffecom_modify (NULL_TREE,
2937 convert (TREE_TYPE (result),
2939 expand_return (result);
2943 ffecom_end_compstmt ();
2945 finish_function (0);
2947 lineno = old_lineno;
2948 input_filename = old_input_filename;
2950 ffecom_doing_entry_ = FALSE;
2954 /* Transform expr into gcc tree with possible destination
2956 Recursive descent on expr while making corresponding tree nodes and
2957 attaching type info and such. If destination supplied and compatible
2958 with temporary that would be made in certain cases, temporary isn't
2959 made, destination used instead, and dest_used flag set TRUE. */
2961 #if FFECOM_targetCURRENT == FFECOM_targetGCC
2963 ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
2964 bool *dest_used, bool assignp, bool widenp)
2969 ffeinfoBasictype bt;
2972 tree dt; /* decl_tree for an ffesymbol. */
2973 tree tree_type, tree_type_x;
2976 enum tree_code code;
2978 assert (expr != NULL);
2980 if (dest_used != NULL)
2983 bt = ffeinfo_basictype (ffebld_info (expr));
2984 kt = ffeinfo_kindtype (ffebld_info (expr));
2985 tree_type = ffecom_tree_type[bt][kt];
2987 /* Widen integral arithmetic as desired while preserving signedness. */
2988 tree_type_x = NULL_TREE;
2989 if (widenp && tree_type
2990 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
2991 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
2992 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
2994 switch (ffebld_op (expr))
2996 case FFEBLD_opACCTER:
2999 ffebit bits = ffebld_accter_bits (expr);
3000 ffetargetOffset source_offset = 0;
3001 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
3004 assert (dest_offset == 0
3005 || (bt == FFEINFO_basictypeCHARACTER
3006 && kt == FFEINFO_kindtypeCHARACTER1));
3011 ffebldConstantUnion cu;
3014 ffebldConstantArray ca = ffebld_accter (expr);
3016 ffebit_test (bits, source_offset, &value, &length);
3022 for (i = 0; i < length; ++i)
3024 cu = ffebld_constantarray_get (ca, bt, kt,
3027 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3030 && dest_offset != 0)
3031 purpose = build_int_2 (dest_offset, 0);
3033 purpose = NULL_TREE;
3035 if (list == NULL_TREE)
3036 list = item = build_tree_list (purpose, t);
3039 TREE_CHAIN (item) = build_tree_list (purpose, t);
3040 item = TREE_CHAIN (item);
3044 source_offset += length;
3045 dest_offset += length;
3049 item = build_int_2 ((ffebld_accter_size (expr)
3050 + ffebld_accter_pad (expr)) - 1, 0);
3051 ffebit_kill (ffebld_accter_bits (expr));
3052 TREE_TYPE (item) = ffecom_integer_type_node;
3056 build_range_type (ffecom_integer_type_node,
3057 ffecom_integer_zero_node,
3059 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3060 TREE_CONSTANT (list) = 1;
3061 TREE_STATIC (list) = 1;
3064 case FFEBLD_opARRTER:
3069 if (ffebld_arrter_pad (expr) == 0)
3073 assert (bt == FFEINFO_basictypeCHARACTER
3074 && kt == FFEINFO_kindtypeCHARACTER1);
3076 /* Becomes PURPOSE first time through loop. */
3077 item = build_int_2 (ffebld_arrter_pad (expr), 0);
3080 for (i = 0; i < ffebld_arrter_size (expr); ++i)
3082 ffebldConstantUnion cu
3083 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
3085 t = ffecom_constantunion (&cu, bt, kt, tree_type);
3087 if (list == NULL_TREE)
3088 /* Assume item is PURPOSE first time through loop. */
3089 list = item = build_tree_list (item, t);
3092 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
3093 item = TREE_CHAIN (item);
3098 item = build_int_2 ((ffebld_arrter_size (expr)
3099 + ffebld_arrter_pad (expr)) - 1, 0);
3100 TREE_TYPE (item) = ffecom_integer_type_node;
3104 build_range_type (ffecom_integer_type_node,
3105 ffecom_integer_zero_node,
3107 list = build (CONSTRUCTOR, item, NULL_TREE, list);
3108 TREE_CONSTANT (list) = 1;
3109 TREE_STATIC (list) = 1;
3112 case FFEBLD_opCONTER:
3113 assert (ffebld_conter_pad (expr) == 0);
3115 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
3119 case FFEBLD_opSYMTER:
3120 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
3121 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
3122 return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */
3123 s = ffebld_symter (expr);
3124 t = ffesymbol_hook (s).decl_tree;
3127 { /* ASSIGN'ed-label expr. */
3128 if (ffe_is_ugly_assign ())
3130 /* User explicitly wants ASSIGN'ed variables to be at the same
3131 memory address as the variables when used in non-ASSIGN
3132 contexts. That can make old, arcane, non-standard code
3133 work, but don't try to do it when a pointer wouldn't fit
3134 in the normal variable (take other approach, and warn,
3139 s = ffecom_sym_transform_ (s);
3140 t = ffesymbol_hook (s).decl_tree;
3141 assert (t != NULL_TREE);
3144 if (t == error_mark_node)
3147 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
3148 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
3150 if (ffesymbol_hook (s).addr)
3151 t = ffecom_1 (INDIRECT_REF,
3152 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3156 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
3158 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3159 FFEBAD_severityWARNING);
3160 ffebad_string (ffesymbol_text (s));
3161 ffebad_here (0, ffesymbol_where_line (s),
3162 ffesymbol_where_column (s));
3167 /* Don't use the normal variable's tree for ASSIGN, though mark
3168 it as in the system header (housekeeping). Use an explicit,
3169 specially created sibling that is known to be wide enough
3170 to hold pointers to labels. */
3173 && TREE_CODE (t) == VAR_DECL)
3174 DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */
3176 t = ffesymbol_hook (s).assign_tree;
3179 s = ffecom_sym_transform_assign_ (s);
3180 t = ffesymbol_hook (s).assign_tree;
3181 assert (t != NULL_TREE);
3188 s = ffecom_sym_transform_ (s);
3189 t = ffesymbol_hook (s).decl_tree;
3190 assert (t != NULL_TREE);
3192 if (ffesymbol_hook (s).addr)
3193 t = ffecom_1 (INDIRECT_REF,
3194 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
3198 case FFEBLD_opARRAYREF:
3199 return ffecom_arrayref_ (NULL_TREE, expr, 0);
3201 case FFEBLD_opUPLUS:
3202 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3203 return ffecom_1 (NOP_EXPR, tree_type, left);
3205 case FFEBLD_opPAREN:
3206 /* ~~~Make sure Fortran rules respected here */
3207 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3208 return ffecom_1 (NOP_EXPR, tree_type, left);
3210 case FFEBLD_opUMINUS:
3211 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3214 tree_type = tree_type_x;
3215 left = convert (tree_type, left);
3217 return ffecom_1 (NEGATE_EXPR, tree_type, left);
3220 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3221 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3224 tree_type = tree_type_x;
3225 left = convert (tree_type, left);
3226 right = convert (tree_type, right);
3228 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
3230 case FFEBLD_opSUBTRACT:
3231 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3232 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3235 tree_type = tree_type_x;
3236 left = convert (tree_type, left);
3237 right = convert (tree_type, right);
3239 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
3241 case FFEBLD_opMULTIPLY:
3242 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3243 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3246 tree_type = tree_type_x;
3247 left = convert (tree_type, left);
3248 right = convert (tree_type, right);
3250 return ffecom_2 (MULT_EXPR, tree_type, left, right);
3252 case FFEBLD_opDIVIDE:
3253 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
3254 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
3257 tree_type = tree_type_x;
3258 left = convert (tree_type, left);
3259 right = convert (tree_type, right);
3261 return ffecom_tree_divide_ (tree_type, left, right,
3262 dest_tree, dest, dest_used,
3263 ffebld_nonter_hook (expr));
3265 case FFEBLD_opPOWER:
3267 ffebld left = ffebld_left (expr);
3268 ffebld right = ffebld_right (expr);
3270 ffeinfoKindtype rtkt;
3271 ffeinfoKindtype ltkt;
3274 switch (ffeinfo_basictype (ffebld_info (right)))
3277 case FFEINFO_basictypeINTEGER:
3280 item = ffecom_expr_power_integer_ (expr);
3281 if (item != NULL_TREE)
3285 rtkt = FFEINFO_kindtypeINTEGER1;
3286 switch (ffeinfo_basictype (ffebld_info (left)))
3288 case FFEINFO_basictypeINTEGER:
3289 if ((ffeinfo_kindtype (ffebld_info (left))
3290 == FFEINFO_kindtypeINTEGER4)
3291 || (ffeinfo_kindtype (ffebld_info (right))
3292 == FFEINFO_kindtypeINTEGER4))
3294 code = FFECOM_gfrtPOW_QQ;
3295 ltkt = FFEINFO_kindtypeINTEGER4;
3296 rtkt = FFEINFO_kindtypeINTEGER4;
3300 code = FFECOM_gfrtPOW_II;
3301 ltkt = FFEINFO_kindtypeINTEGER1;
3305 case FFEINFO_basictypeREAL:
3306 if (ffeinfo_kindtype (ffebld_info (left))
3307 == FFEINFO_kindtypeREAL1)
3309 code = FFECOM_gfrtPOW_RI;
3310 ltkt = FFEINFO_kindtypeREAL1;
3314 code = FFECOM_gfrtPOW_DI;
3315 ltkt = FFEINFO_kindtypeREAL2;
3319 case FFEINFO_basictypeCOMPLEX:
3320 if (ffeinfo_kindtype (ffebld_info (left))
3321 == FFEINFO_kindtypeREAL1)
3323 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3324 ltkt = FFEINFO_kindtypeREAL1;
3328 code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */
3329 ltkt = FFEINFO_kindtypeREAL2;
3334 assert ("bad pow_*i" == NULL);
3335 code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */
3336 ltkt = FFEINFO_kindtypeREAL1;
3339 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
3340 left = ffeexpr_convert (left, NULL, NULL,
3341 ffeinfo_basictype (ffebld_info (left)),
3343 FFETARGET_charactersizeNONE,
3344 FFEEXPR_contextLET);
3345 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
3346 right = ffeexpr_convert (right, NULL, NULL,
3347 FFEINFO_basictypeINTEGER,
3349 FFETARGET_charactersizeNONE,
3350 FFEEXPR_contextLET);
3353 case FFEINFO_basictypeREAL:
3354 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3355 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
3356 FFEINFO_kindtypeREALDOUBLE, 0,
3357 FFETARGET_charactersizeNONE,
3358 FFEEXPR_contextLET);
3359 if (ffeinfo_kindtype (ffebld_info (right))
3360 == FFEINFO_kindtypeREAL1)
3361 right = ffeexpr_convert (right, NULL, NULL,
3362 FFEINFO_basictypeREAL,
3363 FFEINFO_kindtypeREALDOUBLE, 0,
3364 FFETARGET_charactersizeNONE,
3365 FFEEXPR_contextLET);
3366 /* We used to call FFECOM_gfrtPOW_DD here,
3367 which passes arguments by reference. */
3368 code = FFECOM_gfrtL_POW;
3369 /* Pass arguments by value. */
3373 case FFEINFO_basictypeCOMPLEX:
3374 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
3375 left = ffeexpr_convert (left, NULL, NULL,
3376 FFEINFO_basictypeCOMPLEX,
3377 FFEINFO_kindtypeREALDOUBLE, 0,
3378 FFETARGET_charactersizeNONE,
3379 FFEEXPR_contextLET);
3380 if (ffeinfo_kindtype (ffebld_info (right))
3381 == FFEINFO_kindtypeREAL1)
3382 right = ffeexpr_convert (right, NULL, NULL,
3383 FFEINFO_basictypeCOMPLEX,
3384 FFEINFO_kindtypeREALDOUBLE, 0,
3385 FFETARGET_charactersizeNONE,
3386 FFEEXPR_contextLET);
3387 code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */
3388 ref = TRUE; /* Pass arguments by reference. */
3392 assert ("bad pow_x*" == NULL);
3393 code = FFECOM_gfrtPOW_II;
3396 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
3397 ffecom_gfrt_kindtype (code),
3398 (ffe_is_f2c_library ()
3399 && ffecom_gfrt_complex_[code]),
3400 tree_type, left, right,
3401 dest_tree, dest, dest_used,
3402 NULL_TREE, FALSE, ref,
3403 ffebld_nonter_hook (expr));
3409 case FFEINFO_basictypeLOGICAL:
3410 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
3411 return convert (tree_type, item);
3413 case FFEINFO_basictypeINTEGER:
3414 return ffecom_1 (BIT_NOT_EXPR, tree_type,
3415 ffecom_expr (ffebld_left (expr)));
3418 assert ("NOT bad basictype" == NULL);
3420 case FFEINFO_basictypeANY:
3421 return error_mark_node;
3425 case FFEBLD_opFUNCREF:
3426 assert (ffeinfo_basictype (ffebld_info (expr))
3427 != FFEINFO_basictypeCHARACTER);
3429 case FFEBLD_opSUBRREF:
3430 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
3431 == FFEINFO_whereINTRINSIC)
3432 { /* Invocation of an intrinsic. */
3433 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
3437 s = ffebld_symter (ffebld_left (expr));
3438 dt = ffesymbol_hook (s).decl_tree;
3439 if (dt == NULL_TREE)
3441 s = ffecom_sym_transform_ (s);
3442 dt = ffesymbol_hook (s).decl_tree;
3444 if (dt == error_mark_node)
3447 if (ffesymbol_hook (s).addr)
3450 item = ffecom_1_fn (dt);
3452 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
3453 args = ffecom_list_expr (ffebld_right (expr));
3455 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
3457 if (args == error_mark_node)
3458 return error_mark_node;
3460 item = ffecom_call_ (item, kt,
3461 ffesymbol_is_f2c (s)
3462 && (bt == FFEINFO_basictypeCOMPLEX)
3463 && (ffesymbol_where (s)
3464 != FFEINFO_whereCONSTANT),
3467 dest_tree, dest, dest_used,
3468 error_mark_node, FALSE,
3469 ffebld_nonter_hook (expr));
3470 TREE_SIDE_EFFECTS (item) = 1;
3476 case FFEINFO_basictypeLOGICAL:
3478 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3479 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3480 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3481 return convert (tree_type, item);
3483 case FFEINFO_basictypeINTEGER:
3484 return ffecom_2 (BIT_AND_EXPR, tree_type,
3485 ffecom_expr (ffebld_left (expr)),
3486 ffecom_expr (ffebld_right (expr)));
3489 assert ("AND bad basictype" == NULL);
3491 case FFEINFO_basictypeANY:
3492 return error_mark_node;
3499 case FFEINFO_basictypeLOGICAL:
3501 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
3502 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
3503 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
3504 return convert (tree_type, item);
3506 case FFEINFO_basictypeINTEGER:
3507 return ffecom_2 (BIT_IOR_EXPR, tree_type,
3508 ffecom_expr (ffebld_left (expr)),
3509 ffecom_expr (ffebld_right (expr)));
3512 assert ("OR bad basictype" == NULL);
3514 case FFEINFO_basictypeANY:
3515 return error_mark_node;
3523 case FFEINFO_basictypeLOGICAL:
3525 = ffecom_2 (NE_EXPR, integer_type_node,
3526 ffecom_expr (ffebld_left (expr)),
3527 ffecom_expr (ffebld_right (expr)));
3528 return convert (tree_type, ffecom_truth_value (item));
3530 case FFEINFO_basictypeINTEGER:
3531 return ffecom_2 (BIT_XOR_EXPR, tree_type,
3532 ffecom_expr (ffebld_left (expr)),
3533 ffecom_expr (ffebld_right (expr)));
3536 assert ("XOR/NEQV bad basictype" == NULL);
3538 case FFEINFO_basictypeANY:
3539 return error_mark_node;
3546 case FFEINFO_basictypeLOGICAL:
3548 = ffecom_2 (EQ_EXPR, integer_type_node,
3549 ffecom_expr (ffebld_left (expr)),
3550 ffecom_expr (ffebld_right (expr)));
3551 return convert (tree_type, ffecom_truth_value (item));
3553 case FFEINFO_basictypeINTEGER:
3555 ffecom_1 (BIT_NOT_EXPR, tree_type,
3556 ffecom_2 (BIT_XOR_EXPR, tree_type,
3557 ffecom_expr (ffebld_left (expr)),
3558 ffecom_expr (ffebld_right (expr))));
3561 assert ("EQV bad basictype" == NULL);
3563 case FFEINFO_basictypeANY:
3564 return error_mark_node;
3568 case FFEBLD_opCONVERT:
3569 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
3570 return error_mark_node;
3574 case FFEINFO_basictypeLOGICAL:
3575 case FFEINFO_basictypeINTEGER:
3576 case FFEINFO_basictypeREAL:
3577 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3579 case FFEINFO_basictypeCOMPLEX:
3580 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3582 case FFEINFO_basictypeINTEGER:
3583 case FFEINFO_basictypeLOGICAL:
3584 case FFEINFO_basictypeREAL:
3585 item = ffecom_expr (ffebld_left (expr));
3586 if (item == error_mark_node)
3587 return error_mark_node;
3588 /* convert() takes care of converting to the subtype first,
3589 at least in gcc-2.7.2. */
3590 item = convert (tree_type, item);
3593 case FFEINFO_basictypeCOMPLEX:
3594 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
3597 assert ("CONVERT COMPLEX bad basictype" == NULL);
3599 case FFEINFO_basictypeANY:
3600 return error_mark_node;
3605 assert ("CONVERT bad basictype" == NULL);
3607 case FFEINFO_basictypeANY:
3608 return error_mark_node;
3614 goto relational; /* :::::::::::::::::::: */
3618 goto relational; /* :::::::::::::::::::: */
3622 goto relational; /* :::::::::::::::::::: */
3626 goto relational; /* :::::::::::::::::::: */
3630 goto relational; /* :::::::::::::::::::: */
3635 relational: /* :::::::::::::::::::: */
3636 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
3638 case FFEINFO_basictypeLOGICAL:
3639 case FFEINFO_basictypeINTEGER:
3640 case FFEINFO_basictypeREAL:
3641 item = ffecom_2 (code, integer_type_node,
3642 ffecom_expr (ffebld_left (expr)),
3643 ffecom_expr (ffebld_right (expr)));
3644 return convert (tree_type, item);
3646 case FFEINFO_basictypeCOMPLEX:
3647 assert (code == EQ_EXPR || code == NE_EXPR);
3650 tree arg1 = ffecom_expr (ffebld_left (expr));
3651 tree arg2 = ffecom_expr (ffebld_right (expr));
3653 if (arg1 == error_mark_node || arg2 == error_mark_node)
3654 return error_mark_node;
3656 arg1 = ffecom_save_tree (arg1);
3657 arg2 = ffecom_save_tree (arg2);
3659 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
3661 real_type = TREE_TYPE (TREE_TYPE (arg1));
3662 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
3666 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
3667 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
3671 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
3672 ffecom_2 (EQ_EXPR, integer_type_node,
3673 ffecom_1 (REALPART_EXPR, real_type, arg1),
3674 ffecom_1 (REALPART_EXPR, real_type, arg2)),
3675 ffecom_2 (EQ_EXPR, integer_type_node,
3676 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
3677 ffecom_1 (IMAGPART_EXPR, real_type,
3679 if (code == EQ_EXPR)
3680 item = ffecom_truth_value (item);
3682 item = ffecom_truth_value_invert (item);
3683 return convert (tree_type, item);
3686 case FFEINFO_basictypeCHARACTER:
3688 ffebld left = ffebld_left (expr);
3689 ffebld right = ffebld_right (expr);
3695 /* f2c run-time functions do the implicit blank-padding for us,
3696 so we don't usually have to implement blank-padding ourselves.
3697 (The exception is when we pass an argument to a separately
3698 compiled statement function -- if we know the arg is not the
3699 same length as the dummy, we must truncate or extend it. If
3700 we "inline" statement functions, that necessity goes away as
3703 Strip off the CONVERT operators that blank-pad. (Truncation by
3704 CONVERT shouldn't happen here, but it can happen in
3707 while (ffebld_op (left) == FFEBLD_opCONVERT)
3708 left = ffebld_left (left);
3709 while (ffebld_op (right) == FFEBLD_opCONVERT)
3710 right = ffebld_left (right);
3712 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
3713 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
3715 if (left_tree == error_mark_node || left_length == error_mark_node
3716 || right_tree == error_mark_node
3717 || right_length == error_mark_node)
3718 return error_mark_node;
3720 if ((ffebld_size_known (left) == 1)
3721 && (ffebld_size_known (right) == 1))
3724 = ffecom_1 (INDIRECT_REF,
3725 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3728 = ffecom_1 (INDIRECT_REF,
3729 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3733 = ffecom_2 (code, integer_type_node,
3734 ffecom_2 (ARRAY_REF,
3735 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
3738 ffecom_2 (ARRAY_REF,
3739 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
3745 item = build_tree_list (NULL_TREE, left_tree);
3746 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
3747 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
3749 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
3750 = build_tree_list (NULL_TREE, right_length);
3751 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
3752 item = ffecom_2 (code, integer_type_node,
3754 convert (TREE_TYPE (item),
3755 integer_zero_node));
3757 item = convert (tree_type, item);
3763 assert ("relational bad basictype" == NULL);
3765 case FFEINFO_basictypeANY:
3766 return error_mark_node;
3770 case FFEBLD_opPERCENT_LOC:
3771 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
3772 return convert (tree_type, item);
3776 case FFEBLD_opBOUNDS:
3777 case FFEBLD_opREPEAT:
3778 case FFEBLD_opLABTER:
3779 case FFEBLD_opLABTOK:
3780 case FFEBLD_opIMPDO:
3781 case FFEBLD_opCONCATENATE:
3782 case FFEBLD_opSUBSTR:
3784 assert ("bad op" == NULL);
3787 return error_mark_node;
3791 assert ("didn't think anything got here anymore!!" == NULL);
3793 switch (ffebld_arity (expr))
3796 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3797 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
3798 if (TREE_OPERAND (item, 0) == error_mark_node
3799 || TREE_OPERAND (item, 1) == error_mark_node)
3800 return error_mark_node;
3804 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
3805 if (TREE_OPERAND (item, 0) == error_mark_node)
3806 return error_mark_node;
3818 /* Returns the tree that does the intrinsic invocation.
3820 Note: this function applies only to intrinsics returning
3821 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3824 #if FFECOM_targetCURRENT == FFECOM_targetGCC
3826 ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
3827 ffebld dest, bool *dest_used)
3830 tree saved_expr1; /* For those who need it. */
3831 tree saved_expr2; /* For those who need it. */
3832 ffeinfoBasictype bt;
3836 tree real_type; /* REAL type corresponding to COMPLEX. */
3838 ffebld list = ffebld_right (expr); /* List of (some) args. */
3839 ffebld arg1; /* For handy reference. */
3842 ffeintrinImp codegen_imp;
3845 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
3847 if (dest_used != NULL)
3850 bt = ffeinfo_basictype (ffebld_info (expr));
3851 kt = ffeinfo_kindtype (ffebld_info (expr));
3852 tree_type = ffecom_tree_type[bt][kt];
3856 arg1 = ffebld_head (list);
3857 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
3858 return error_mark_node;
3859 if ((list = ffebld_trail (list)) != NULL)
3861 arg2 = ffebld_head (list);
3862 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
3863 return error_mark_node;
3864 if ((list = ffebld_trail (list)) != NULL)
3866 arg3 = ffebld_head (list);
3867 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
3868 return error_mark_node;
3877 arg1 = arg2 = arg3 = NULL;
3879 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3880 args. This is used by the MAX/MIN expansions. */
3883 arg1_type = ffecom_tree_type
3884 [ffeinfo_basictype (ffebld_info (arg1))]
3885 [ffeinfo_kindtype (ffebld_info (arg1))];
3887 arg1_type = NULL_TREE; /* Really not needed, but might catch bugs
3890 /* There are several ways for each of the cases in the following switch
3891 statements to exit (from simplest to use to most complicated):
3893 break; (when expr_tree == NULL)
3895 A standard call is made to the specific intrinsic just as if it had been
3896 passed in as a dummy procedure and called as any old procedure. This
3897 method can produce slower code but in some cases it's the easiest way for
3898 now. However, if a (presumably faster) direct call is available,
3899 that is used, so this is the easiest way in many more cases now.
3901 gfrt = FFECOM_gfrtWHATEVER;
3904 gfrt contains the gfrt index of a library function to call, passing the
3905 argument(s) by value rather than by reference. Used when a more
3906 careful choice of library function is needed than that provided
3907 by the vanilla `break;'.
3911 The expr_tree has been completely set up and is ready to be returned
3912 as is. No further actions are taken. Use this when the tree is not
3913 in the simple form for one of the arity_n labels. */
3915 /* For info on how the switch statement cases were written, see the files
3916 enclosed in comments below the switch statement. */
3918 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
3919 gfrt = ffeintrin_gfrt_direct (codegen_imp);
3920 if (gfrt == FFECOM_gfrt)
3921 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
3923 switch (codegen_imp)
3925 case FFEINTRIN_impABS:
3926 case FFEINTRIN_impCABS:
3927 case FFEINTRIN_impCDABS:
3928 case FFEINTRIN_impDABS:
3929 case FFEINTRIN_impIABS:
3930 if (ffeinfo_basictype (ffebld_info (arg1))
3931 == FFEINFO_basictypeCOMPLEX)
3933 if (kt == FFEINFO_kindtypeREAL1)
3934 gfrt = FFECOM_gfrtCABS;
3935 else if (kt == FFEINFO_kindtypeREAL2)
3936 gfrt = FFECOM_gfrtCDABS;
3939 return ffecom_1 (ABS_EXPR, tree_type,
3940 convert (tree_type, ffecom_expr (arg1)));
3942 case FFEINTRIN_impACOS:
3943 case FFEINTRIN_impDACOS:
3946 case FFEINTRIN_impAIMAG:
3947 case FFEINTRIN_impDIMAG:
3948 case FFEINTRIN_impIMAGPART:
3949 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
3950 arg1_type = TREE_TYPE (arg1_type);
3952 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
3956 ffecom_1 (IMAGPART_EXPR, arg1_type,
3957 ffecom_expr (arg1)));
3959 case FFEINTRIN_impAINT:
3960 case FFEINTRIN_impDINT:
3962 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
3963 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
3964 #else /* in the meantime, must use floor to avoid range problems with ints */
3965 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
3966 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3969 ffecom_3 (COND_EXPR, double_type_node,
3971 (ffecom_2 (GE_EXPR, integer_type_node,
3974 ffecom_float_zero_))),
3975 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3976 build_tree_list (NULL_TREE,
3977 convert (double_type_node,
3980 ffecom_1 (NEGATE_EXPR, double_type_node,
3981 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
3982 build_tree_list (NULL_TREE,
3983 convert (double_type_node,
3984 ffecom_1 (NEGATE_EXPR,
3992 case FFEINTRIN_impANINT:
3993 case FFEINTRIN_impDNINT:
3994 #if 0 /* This way of doing it won't handle real
3995 numbers of large magnitudes. */
3996 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
3997 expr_tree = convert (tree_type,
3998 convert (integer_type_node,
3999 ffecom_3 (COND_EXPR, tree_type,
4004 ffecom_float_zero_)),
4005 ffecom_2 (PLUS_EXPR,
4008 ffecom_float_half_),
4009 ffecom_2 (MINUS_EXPR,
4012 ffecom_float_half_))));
4014 #else /* So we instead call floor. */
4015 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
4016 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4019 ffecom_3 (COND_EXPR, double_type_node,
4021 (ffecom_2 (GE_EXPR, integer_type_node,
4024 ffecom_float_zero_))),
4025 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4026 build_tree_list (NULL_TREE,
4027 convert (double_type_node,
4028 ffecom_2 (PLUS_EXPR,
4032 ffecom_float_half_)))),
4034 ffecom_1 (NEGATE_EXPR, double_type_node,
4035 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
4036 build_tree_list (NULL_TREE,
4037 convert (double_type_node,
4038 ffecom_2 (MINUS_EXPR,
4041 ffecom_float_half_),
4048 case FFEINTRIN_impASIN:
4049 case FFEINTRIN_impDASIN:
4050 case FFEINTRIN_impATAN:
4051 case FFEINTRIN_impDATAN:
4052 case FFEINTRIN_impATAN2:
4053 case FFEINTRIN_impDATAN2:
4056 case FFEINTRIN_impCHAR:
4057 case FFEINTRIN_impACHAR:
4059 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
4061 tempvar = ffebld_nonter_hook (expr);
4065 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
4067 expr_tree = ffecom_modify (tmv,
4068 ffecom_2 (ARRAY_REF, tmv, tempvar,
4070 convert (tmv, ffecom_expr (arg1)));
4072 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
4075 expr_tree = ffecom_1 (ADDR_EXPR,
4076 build_pointer_type (TREE_TYPE (expr_tree)),
4080 case FFEINTRIN_impCMPLX:
4081 case FFEINTRIN_impDCMPLX:
4084 convert (tree_type, ffecom_expr (arg1));
4086 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4088 ffecom_2 (COMPLEX_EXPR, tree_type,
4089 convert (real_type, ffecom_expr (arg1)),
4091 ffecom_expr (arg2)));
4093 case FFEINTRIN_impCOMPLEX:
4095 ffecom_2 (COMPLEX_EXPR, tree_type,
4097 ffecom_expr (arg2));
4099 case FFEINTRIN_impCONJG:
4100 case FFEINTRIN_impDCONJG:
4104 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
4105 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4107 ffecom_2 (COMPLEX_EXPR, tree_type,
4108 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
4109 ffecom_1 (NEGATE_EXPR, real_type,
4110 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
4113 case FFEINTRIN_impCOS:
4114 case FFEINTRIN_impCCOS:
4115 case FFEINTRIN_impCDCOS:
4116 case FFEINTRIN_impDCOS:
4117 if (bt == FFEINFO_basictypeCOMPLEX)
4119 if (kt == FFEINFO_kindtypeREAL1)
4120 gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */
4121 else if (kt == FFEINFO_kindtypeREAL2)
4122 gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */
4126 case FFEINTRIN_impCOSH:
4127 case FFEINTRIN_impDCOSH:
4130 case FFEINTRIN_impDBLE:
4131 case FFEINTRIN_impDFLOAT:
4132 case FFEINTRIN_impDREAL:
4133 case FFEINTRIN_impFLOAT:
4134 case FFEINTRIN_impIDINT:
4135 case FFEINTRIN_impIFIX:
4136 case FFEINTRIN_impINT2:
4137 case FFEINTRIN_impINT8:
4138 case FFEINTRIN_impINT:
4139 case FFEINTRIN_impLONG:
4140 case FFEINTRIN_impREAL:
4141 case FFEINTRIN_impSHORT:
4142 case FFEINTRIN_impSNGL:
4143 return convert (tree_type, ffecom_expr (arg1));
4145 case FFEINTRIN_impDIM:
4146 case FFEINTRIN_impDDIM:
4147 case FFEINTRIN_impIDIM:
4148 saved_expr1 = ffecom_save_tree (convert (tree_type,
4149 ffecom_expr (arg1)));
4150 saved_expr2 = ffecom_save_tree (convert (tree_type,
4151 ffecom_expr (arg2)));
4153 ffecom_3 (COND_EXPR, tree_type,
4155 (ffecom_2 (GT_EXPR, integer_type_node,
4158 ffecom_2 (MINUS_EXPR, tree_type,
4161 convert (tree_type, ffecom_float_zero_));
4163 case FFEINTRIN_impDPROD:
4165 ffecom_2 (MULT_EXPR, tree_type,
4166 convert (tree_type, ffecom_expr (arg1)),
4167 convert (tree_type, ffecom_expr (arg2)));
4169 case FFEINTRIN_impEXP:
4170 case FFEINTRIN_impCDEXP:
4171 case FFEINTRIN_impCEXP:
4172 case FFEINTRIN_impDEXP:
4173 if (bt == FFEINFO_basictypeCOMPLEX)
4175 if (kt == FFEINFO_kindtypeREAL1)
4176 gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */
4177 else if (kt == FFEINFO_kindtypeREAL2)
4178 gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */
4182 case FFEINTRIN_impICHAR:
4183 case FFEINTRIN_impIACHAR:
4184 #if 0 /* The simple approach. */
4185 ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1);
4187 = ffecom_1 (INDIRECT_REF,
4188 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4191 = ffecom_2 (ARRAY_REF,
4192 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
4195 return convert (tree_type, expr_tree);
4196 #else /* The more interesting (and more optimal) approach. */
4197 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
4198 expr_tree = ffecom_3 (COND_EXPR, tree_type,
4201 convert (tree_type, integer_zero_node));
4205 case FFEINTRIN_impINDEX:
4208 case FFEINTRIN_impLEN:
4210 break; /* The simple approach. */
4212 return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */
4215 case FFEINTRIN_impLGE:
4216 case FFEINTRIN_impLGT:
4217 case FFEINTRIN_impLLE:
4218 case FFEINTRIN_impLLT:
4221 case FFEINTRIN_impLOG:
4222 case FFEINTRIN_impALOG:
4223 case FFEINTRIN_impCDLOG:
4224 case FFEINTRIN_impCLOG:
4225 case FFEINTRIN_impDLOG:
4226 if (bt == FFEINFO_basictypeCOMPLEX)
4228 if (kt == FFEINFO_kindtypeREAL1)
4229 gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */
4230 else if (kt == FFEINFO_kindtypeREAL2)
4231 gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */
4235 case FFEINTRIN_impLOG10:
4236 case FFEINTRIN_impALOG10:
4237 case FFEINTRIN_impDLOG10:
4238 if (gfrt != FFECOM_gfrt)
4239 break; /* Already picked one, stick with it. */
4241 if (kt == FFEINFO_kindtypeREAL1)
4242 /* We used to call FFECOM_gfrtALOG10 here. */
4243 gfrt = FFECOM_gfrtL_LOG10;
4244 else if (kt == FFEINFO_kindtypeREAL2)
4245 /* We used to call FFECOM_gfrtDLOG10 here. */
4246 gfrt = FFECOM_gfrtL_LOG10;
4249 case FFEINTRIN_impMAX:
4250 case FFEINTRIN_impAMAX0:
4251 case FFEINTRIN_impAMAX1:
4252 case FFEINTRIN_impDMAX1:
4253 case FFEINTRIN_impMAX0:
4254 case FFEINTRIN_impMAX1:
4255 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4256 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4258 arg1_type = tree_type;
4259 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4260 convert (arg1_type, ffecom_expr (arg1)),
4261 convert (arg1_type, ffecom_expr (arg2)));
4262 for (; list != NULL; list = ffebld_trail (list))
4264 if ((ffebld_head (list) == NULL)
4265 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4267 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
4270 ffecom_expr (ffebld_head (list))));
4272 return convert (tree_type, expr_tree);
4274 case FFEINTRIN_impMIN:
4275 case FFEINTRIN_impAMIN0:
4276 case FFEINTRIN_impAMIN1:
4277 case FFEINTRIN_impDMIN1:
4278 case FFEINTRIN_impMIN0:
4279 case FFEINTRIN_impMIN1:
4280 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
4281 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
4283 arg1_type = tree_type;
4284 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4285 convert (arg1_type, ffecom_expr (arg1)),
4286 convert (arg1_type, ffecom_expr (arg2)));
4287 for (; list != NULL; list = ffebld_trail (list))
4289 if ((ffebld_head (list) == NULL)
4290 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
4292 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
4295 ffecom_expr (ffebld_head (list))));
4297 return convert (tree_type, expr_tree);
4299 case FFEINTRIN_impMOD:
4300 case FFEINTRIN_impAMOD:
4301 case FFEINTRIN_impDMOD:
4302 if (bt != FFEINFO_basictypeREAL)
4303 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
4304 convert (tree_type, ffecom_expr (arg1)),
4305 convert (tree_type, ffecom_expr (arg2)));
4307 if (kt == FFEINFO_kindtypeREAL1)
4308 /* We used to call FFECOM_gfrtAMOD here. */
4309 gfrt = FFECOM_gfrtL_FMOD;
4310 else if (kt == FFEINFO_kindtypeREAL2)
4311 /* We used to call FFECOM_gfrtDMOD here. */
4312 gfrt = FFECOM_gfrtL_FMOD;
4315 case FFEINTRIN_impNINT:
4316 case FFEINTRIN_impIDNINT:
4318 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
4319 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
4321 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4322 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
4324 convert (ffecom_integer_type_node,
4325 ffecom_3 (COND_EXPR, arg1_type,
4327 (ffecom_2 (GE_EXPR, integer_type_node,
4330 ffecom_float_zero_))),
4331 ffecom_2 (PLUS_EXPR, arg1_type,
4334 ffecom_float_half_)),
4335 ffecom_2 (MINUS_EXPR, arg1_type,
4338 ffecom_float_half_))));
4341 case FFEINTRIN_impSIGN:
4342 case FFEINTRIN_impDSIGN:
4343 case FFEINTRIN_impISIGN:
4345 tree arg2_tree = ffecom_expr (arg2);
4349 (ffecom_1 (ABS_EXPR, tree_type,
4351 ffecom_expr (arg1))));
4353 = ffecom_3 (COND_EXPR, tree_type,
4355 (ffecom_2 (GE_EXPR, integer_type_node,
4357 convert (TREE_TYPE (arg2_tree),
4358 integer_zero_node))),
4360 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
4361 /* Make sure SAVE_EXPRs get referenced early enough. */
4363 = ffecom_2 (COMPOUND_EXPR, tree_type,
4364 convert (void_type_node, saved_expr1),
4369 case FFEINTRIN_impSIN:
4370 case FFEINTRIN_impCDSIN:
4371 case FFEINTRIN_impCSIN:
4372 case FFEINTRIN_impDSIN:
4373 if (bt == FFEINFO_basictypeCOMPLEX)
4375 if (kt == FFEINFO_kindtypeREAL1)
4376 gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */
4377 else if (kt == FFEINFO_kindtypeREAL2)
4378 gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */
4382 case FFEINTRIN_impSINH:
4383 case FFEINTRIN_impDSINH:
4386 case FFEINTRIN_impSQRT:
4387 case FFEINTRIN_impCDSQRT:
4388 case FFEINTRIN_impCSQRT:
4389 case FFEINTRIN_impDSQRT:
4390 if (bt == FFEINFO_basictypeCOMPLEX)
4392 if (kt == FFEINFO_kindtypeREAL1)
4393 gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */
4394 else if (kt == FFEINFO_kindtypeREAL2)
4395 gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */
4399 case FFEINTRIN_impTAN:
4400 case FFEINTRIN_impDTAN:
4401 case FFEINTRIN_impTANH:
4402 case FFEINTRIN_impDTANH:
4405 case FFEINTRIN_impREALPART:
4406 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
4407 arg1_type = TREE_TYPE (arg1_type);
4409 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
4413 ffecom_1 (REALPART_EXPR, arg1_type,
4414 ffecom_expr (arg1)));
4416 case FFEINTRIN_impIAND:
4417 case FFEINTRIN_impAND:
4418 return ffecom_2 (BIT_AND_EXPR, tree_type,
4420 ffecom_expr (arg1)),
4422 ffecom_expr (arg2)));
4424 case FFEINTRIN_impIOR:
4425 case FFEINTRIN_impOR:
4426 return ffecom_2 (BIT_IOR_EXPR, tree_type,
4428 ffecom_expr (arg1)),
4430 ffecom_expr (arg2)));
4432 case FFEINTRIN_impIEOR:
4433 case FFEINTRIN_impXOR:
4434 return ffecom_2 (BIT_XOR_EXPR, tree_type,
4436 ffecom_expr (arg1)),
4438 ffecom_expr (arg2)));
4440 case FFEINTRIN_impLSHIFT:
4441 return ffecom_2 (LSHIFT_EXPR, tree_type,
4443 convert (integer_type_node,
4444 ffecom_expr (arg2)));
4446 case FFEINTRIN_impRSHIFT:
4447 return ffecom_2 (RSHIFT_EXPR, tree_type,
4449 convert (integer_type_node,
4450 ffecom_expr (arg2)));
4452 case FFEINTRIN_impNOT:
4453 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
4455 case FFEINTRIN_impBIT_SIZE:
4456 return convert (tree_type, TYPE_SIZE (arg1_type));
4458 case FFEINTRIN_impBTEST:
4460 ffetargetLogical1 target_true;
4461 ffetargetLogical1 target_false;
4465 ffetarget_logical1 (&target_true, TRUE);
4466 ffetarget_logical1 (&target_false, FALSE);
4467 if (target_true == 1)
4468 true_tree = convert (tree_type, integer_one_node);
4470 true_tree = convert (tree_type, build_int_2 (target_true, 0));
4471 if (target_false == 0)
4472 false_tree = convert (tree_type, integer_zero_node);
4474 false_tree = convert (tree_type, build_int_2 (target_false, 0));
4477 ffecom_3 (COND_EXPR, tree_type,
4479 (ffecom_2 (EQ_EXPR, integer_type_node,
4480 ffecom_2 (BIT_AND_EXPR, arg1_type,
4482 ffecom_2 (LSHIFT_EXPR, arg1_type,
4485 convert (integer_type_node,
4486 ffecom_expr (arg2)))),
4488 integer_zero_node))),
4493 case FFEINTRIN_impIBCLR:
4495 ffecom_2 (BIT_AND_EXPR, tree_type,
4497 ffecom_1 (BIT_NOT_EXPR, tree_type,
4498 ffecom_2 (LSHIFT_EXPR, tree_type,
4501 convert (integer_type_node,
4502 ffecom_expr (arg2)))));
4504 case FFEINTRIN_impIBITS:
4506 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
4507 ffecom_expr (arg3)));
4509 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4512 = ffecom_2 (BIT_AND_EXPR, tree_type,
4513 ffecom_2 (RSHIFT_EXPR, tree_type,
4515 convert (integer_type_node,
4516 ffecom_expr (arg2))),
4518 ffecom_2 (RSHIFT_EXPR, uns_type,
4519 ffecom_1 (BIT_NOT_EXPR,
4522 integer_zero_node)),
4523 ffecom_2 (MINUS_EXPR,
4525 TYPE_SIZE (uns_type),
4527 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4529 = ffecom_3 (COND_EXPR, tree_type,
4531 (ffecom_2 (NE_EXPR, integer_type_node,
4533 integer_zero_node)),
4535 convert (tree_type, integer_zero_node));
4540 case FFEINTRIN_impIBSET:
4542 ffecom_2 (BIT_IOR_EXPR, tree_type,
4544 ffecom_2 (LSHIFT_EXPR, tree_type,
4545 convert (tree_type, integer_one_node),
4546 convert (integer_type_node,
4547 ffecom_expr (arg2))));
4549 case FFEINTRIN_impISHFT:
4551 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4552 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4553 ffecom_expr (arg2)));
4555 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4558 = ffecom_3 (COND_EXPR, tree_type,
4560 (ffecom_2 (GE_EXPR, integer_type_node,
4562 integer_zero_node)),
4563 ffecom_2 (LSHIFT_EXPR, tree_type,
4567 ffecom_2 (RSHIFT_EXPR, uns_type,
4568 convert (uns_type, arg1_tree),
4569 ffecom_1 (NEGATE_EXPR,
4572 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4574 = ffecom_3 (COND_EXPR, tree_type,
4576 (ffecom_2 (LT_EXPR, integer_type_node,
4580 TYPE_SIZE (uns_type))),
4582 convert (tree_type, integer_zero_node));
4584 /* Make sure SAVE_EXPRs get referenced early enough. */
4586 = ffecom_2 (COMPOUND_EXPR, tree_type,
4587 convert (void_type_node, arg1_tree),
4588 ffecom_2 (COMPOUND_EXPR, tree_type,
4589 convert (void_type_node, arg2_tree),
4594 case FFEINTRIN_impISHFTC:
4596 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
4597 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
4598 ffecom_expr (arg2)));
4599 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
4600 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
4606 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
4609 = ffecom_2 (LSHIFT_EXPR, tree_type,
4610 ffecom_1 (BIT_NOT_EXPR, tree_type,
4611 convert (tree_type, integer_zero_node)),
4613 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4615 = ffecom_3 (COND_EXPR, tree_type,
4617 (ffecom_2 (NE_EXPR, integer_type_node,
4619 TYPE_SIZE (uns_type))),
4621 convert (tree_type, integer_zero_node));
4623 mask_arg1 = ffecom_save_tree (mask_arg1);
4625 = ffecom_2 (BIT_AND_EXPR, tree_type,
4627 ffecom_1 (BIT_NOT_EXPR, tree_type,
4629 masked_arg1 = ffecom_save_tree (masked_arg1);
4631 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4633 ffecom_2 (RSHIFT_EXPR, uns_type,
4634 convert (uns_type, masked_arg1),
4635 ffecom_1 (NEGATE_EXPR,
4638 ffecom_2 (LSHIFT_EXPR, tree_type,
4640 ffecom_2 (PLUS_EXPR, integer_type_node,
4644 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4645 ffecom_2 (LSHIFT_EXPR, tree_type,
4649 ffecom_2 (RSHIFT_EXPR, uns_type,
4650 convert (uns_type, masked_arg1),
4651 ffecom_2 (MINUS_EXPR,
4656 = ffecom_3 (COND_EXPR, tree_type,
4658 (ffecom_2 (LT_EXPR, integer_type_node,
4660 integer_zero_node)),
4664 = ffecom_2 (BIT_IOR_EXPR, tree_type,
4665 ffecom_2 (BIT_AND_EXPR, tree_type,
4668 ffecom_2 (BIT_AND_EXPR, tree_type,
4669 ffecom_1 (BIT_NOT_EXPR, tree_type,
4673 = ffecom_3 (COND_EXPR, tree_type,
4675 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
4676 ffecom_2 (EQ_EXPR, integer_type_node,
4681 ffecom_2 (EQ_EXPR, integer_type_node,
4683 integer_zero_node))),
4686 /* Make sure SAVE_EXPRs get referenced early enough. */
4688 = ffecom_2 (COMPOUND_EXPR, tree_type,
4689 convert (void_type_node, arg1_tree),
4690 ffecom_2 (COMPOUND_EXPR, tree_type,
4691 convert (void_type_node, arg2_tree),
4692 ffecom_2 (COMPOUND_EXPR, tree_type,
4693 convert (void_type_node,
4695 ffecom_2 (COMPOUND_EXPR, tree_type,
4696 convert (void_type_node,
4700 = ffecom_2 (COMPOUND_EXPR, tree_type,
4701 convert (void_type_node,
4707 case FFEINTRIN_impLOC:
4709 tree arg1_tree = ffecom_expr (arg1);
4712 = convert (tree_type,
4713 ffecom_1 (ADDR_EXPR,
4714 build_pointer_type (TREE_TYPE (arg1_tree)),
4719 case FFEINTRIN_impMVBITS:
4724 ffebld arg4 = ffebld_head (ffebld_trail (list));
4727 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
4731 tree arg5_plus_arg3;
4733 arg2_tree = convert (integer_type_node,
4734 ffecom_expr (arg2));
4735 arg3_tree = ffecom_save_tree (convert (integer_type_node,
4736 ffecom_expr (arg3)));
4737 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
4738 arg4_type = TREE_TYPE (arg4_tree);
4740 arg1_tree = ffecom_save_tree (convert (arg4_type,
4741 ffecom_expr (arg1)));
4743 arg5_tree = ffecom_save_tree (convert (integer_type_node,
4744 ffecom_expr (arg5)));
4747 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4748 ffecom_2 (BIT_AND_EXPR, arg4_type,
4749 ffecom_2 (RSHIFT_EXPR, arg4_type,
4752 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4753 ffecom_2 (LSHIFT_EXPR, arg4_type,
4754 ffecom_1 (BIT_NOT_EXPR,
4758 integer_zero_node)),
4762 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
4766 = ffecom_2 (LSHIFT_EXPR, arg4_type,
4767 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4769 integer_zero_node)),
4771 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4773 = ffecom_3 (COND_EXPR, arg4_type,
4775 (ffecom_2 (NE_EXPR, integer_type_node,
4777 convert (TREE_TYPE (arg5_plus_arg3),
4778 TYPE_SIZE (arg4_type)))),
4780 convert (arg4_type, integer_zero_node));
4783 = ffecom_2 (BIT_AND_EXPR, arg4_type,
4785 ffecom_2 (BIT_IOR_EXPR, arg4_type,
4787 ffecom_1 (BIT_NOT_EXPR, arg4_type,
4788 ffecom_2 (LSHIFT_EXPR, arg4_type,
4789 ffecom_1 (BIT_NOT_EXPR,
4793 integer_zero_node)),
4796 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
4799 #if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH
4801 = ffecom_3 (COND_EXPR, arg4_type,
4803 (ffecom_2 (NE_EXPR, integer_type_node,
4805 convert (TREE_TYPE (arg3_tree),
4806 integer_zero_node))),
4810 = ffecom_3 (COND_EXPR, arg4_type,
4812 (ffecom_2 (NE_EXPR, integer_type_node,
4814 convert (TREE_TYPE (arg3_tree),
4815 TYPE_SIZE (arg4_type)))),
4820 = ffecom_2s (MODIFY_EXPR, void_type_node,
4823 /* Make sure SAVE_EXPRs get referenced early enough. */
4825 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4827 ffecom_2 (COMPOUND_EXPR, void_type_node,
4829 ffecom_2 (COMPOUND_EXPR, void_type_node,
4831 ffecom_2 (COMPOUND_EXPR, void_type_node,
4835 = ffecom_2 (COMPOUND_EXPR, void_type_node,
4842 case FFEINTRIN_impDERF:
4843 case FFEINTRIN_impERF:
4844 case FFEINTRIN_impDERFC:
4845 case FFEINTRIN_impERFC:
4848 case FFEINTRIN_impIARGC:
4849 /* extern int xargc; i__1 = xargc - 1; */
4850 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
4852 convert (TREE_TYPE (ffecom_tree_xargc_),
4856 case FFEINTRIN_impSIGNAL_func:
4857 case FFEINTRIN_impSIGNAL_subr:
4863 arg1_tree = convert (ffecom_f2c_integer_type_node,
4864 ffecom_expr (arg1));
4865 arg1_tree = ffecom_1 (ADDR_EXPR,
4866 build_pointer_type (TREE_TYPE (arg1_tree)),
4869 /* Pass procedure as a pointer to it, anything else by value. */
4870 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4871 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4873 arg2_tree = ffecom_ptr_to_expr (arg2);
4874 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4878 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4880 arg3_tree = NULL_TREE;
4882 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4883 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4884 TREE_CHAIN (arg1_tree) = arg2_tree;
4887 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4888 ffecom_gfrt_kindtype (gfrt),
4890 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
4894 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4895 ffebld_nonter_hook (expr));
4897 if (arg3_tree != NULL_TREE)
4899 = ffecom_modify (NULL_TREE, arg3_tree,
4900 convert (TREE_TYPE (arg3_tree),
4905 case FFEINTRIN_impALARM:
4911 arg1_tree = convert (ffecom_f2c_integer_type_node,
4912 ffecom_expr (arg1));
4913 arg1_tree = ffecom_1 (ADDR_EXPR,
4914 build_pointer_type (TREE_TYPE (arg1_tree)),
4917 /* Pass procedure as a pointer to it, anything else by value. */
4918 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
4919 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
4921 arg2_tree = ffecom_ptr_to_expr (arg2);
4922 arg2_tree = convert (TREE_TYPE (null_pointer_node),
4926 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
4928 arg3_tree = NULL_TREE;
4930 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4931 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
4932 TREE_CHAIN (arg1_tree) = arg2_tree;
4935 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4936 ffecom_gfrt_kindtype (gfrt),
4940 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4941 ffebld_nonter_hook (expr));
4943 if (arg3_tree != NULL_TREE)
4945 = ffecom_modify (NULL_TREE, arg3_tree,
4946 convert (TREE_TYPE (arg3_tree),
4951 case FFEINTRIN_impCHDIR_subr:
4952 case FFEINTRIN_impFDATE_subr:
4953 case FFEINTRIN_impFGET_subr:
4954 case FFEINTRIN_impFPUT_subr:
4955 case FFEINTRIN_impGETCWD_subr:
4956 case FFEINTRIN_impHOSTNM_subr:
4957 case FFEINTRIN_impSYSTEM_subr:
4958 case FFEINTRIN_impUNLINK_subr:
4960 tree arg1_len = integer_zero_node;
4964 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
4967 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
4969 arg2_tree = NULL_TREE;
4971 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
4972 arg1_len = build_tree_list (NULL_TREE, arg1_len);
4973 TREE_CHAIN (arg1_tree) = arg1_len;
4976 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
4977 ffecom_gfrt_kindtype (gfrt),
4981 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
4982 ffebld_nonter_hook (expr));
4984 if (arg2_tree != NULL_TREE)
4986 = ffecom_modify (NULL_TREE, arg2_tree,
4987 convert (TREE_TYPE (arg2_tree),
4992 case FFEINTRIN_impEXIT:
4996 expr_tree = build_tree_list (NULL_TREE,
4997 ffecom_1 (ADDR_EXPR,
4999 (ffecom_integer_type_node),
5000 integer_zero_node));
5003 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5004 ffecom_gfrt_kindtype (gfrt),
5008 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5009 ffebld_nonter_hook (expr));
5011 case FFEINTRIN_impFLUSH:
5013 gfrt = FFECOM_gfrtFLUSH;
5015 gfrt = FFECOM_gfrtFLUSH1;
5018 case FFEINTRIN_impCHMOD_subr:
5019 case FFEINTRIN_impLINK_subr:
5020 case FFEINTRIN_impRENAME_subr:
5021 case FFEINTRIN_impSYMLNK_subr:
5023 tree arg1_len = integer_zero_node;
5025 tree arg2_len = integer_zero_node;
5029 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5030 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
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 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5040 TREE_CHAIN (arg1_tree) = arg2_tree;
5041 TREE_CHAIN (arg2_tree) = arg1_len;
5042 TREE_CHAIN (arg1_len) = arg2_len;
5043 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5044 ffecom_gfrt_kindtype (gfrt),
5048 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5049 ffebld_nonter_hook (expr));
5050 if (arg3_tree != NULL_TREE)
5051 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5052 convert (TREE_TYPE (arg3_tree),
5057 case FFEINTRIN_impLSTAT_subr:
5058 case FFEINTRIN_impSTAT_subr:
5060 tree arg1_len = integer_zero_node;
5065 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
5067 arg2_tree = ffecom_ptr_to_expr (arg2);
5070 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5072 arg3_tree = NULL_TREE;
5074 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5075 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5076 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5077 TREE_CHAIN (arg1_tree) = arg2_tree;
5078 TREE_CHAIN (arg2_tree) = arg1_len;
5079 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5080 ffecom_gfrt_kindtype (gfrt),
5084 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5085 ffebld_nonter_hook (expr));
5086 if (arg3_tree != NULL_TREE)
5087 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5088 convert (TREE_TYPE (arg3_tree),
5093 case FFEINTRIN_impFGETC_subr:
5094 case FFEINTRIN_impFPUTC_subr:
5098 tree arg2_len = integer_zero_node;
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 = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
5109 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5111 arg3_tree = NULL_TREE;
5113 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5114 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5115 arg2_len = build_tree_list (NULL_TREE, arg2_len);
5116 TREE_CHAIN (arg1_tree) = arg2_tree;
5117 TREE_CHAIN (arg2_tree) = arg2_len;
5119 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5120 ffecom_gfrt_kindtype (gfrt),
5124 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5125 ffebld_nonter_hook (expr));
5126 if (arg3_tree != NULL_TREE)
5127 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5128 convert (TREE_TYPE (arg3_tree),
5133 case FFEINTRIN_impFSTAT_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_ptr_to_integer_type_node,
5146 ffecom_ptr_to_expr (arg2));
5149 arg3_tree = NULL_TREE;
5151 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5153 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5154 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5155 TREE_CHAIN (arg1_tree) = arg2_tree;
5156 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5157 ffecom_gfrt_kindtype (gfrt),
5161 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5162 ffebld_nonter_hook (expr));
5163 if (arg3_tree != NULL_TREE) {
5164 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5165 convert (TREE_TYPE (arg3_tree),
5171 case FFEINTRIN_impKILL_subr:
5177 arg1_tree = convert (ffecom_f2c_integer_type_node,
5178 ffecom_expr (arg1));
5179 arg1_tree = ffecom_1 (ADDR_EXPR,
5180 build_pointer_type (TREE_TYPE (arg1_tree)),
5183 arg2_tree = convert (ffecom_f2c_integer_type_node,
5184 ffecom_expr (arg2));
5185 arg2_tree = ffecom_1 (ADDR_EXPR,
5186 build_pointer_type (TREE_TYPE (arg2_tree)),
5190 arg3_tree = NULL_TREE;
5192 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
5194 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5195 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5196 TREE_CHAIN (arg1_tree) = arg2_tree;
5197 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5198 ffecom_gfrt_kindtype (gfrt),
5202 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5203 ffebld_nonter_hook (expr));
5204 if (arg3_tree != NULL_TREE) {
5205 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
5206 convert (TREE_TYPE (arg3_tree),
5212 case FFEINTRIN_impCTIME_subr:
5213 case FFEINTRIN_impTTYNAM_subr:
5215 tree arg1_len = integer_zero_node;
5219 arg1_tree = ffecom_arg_ptr_to_expr (arg2, &arg1_len);
5221 arg2_tree = convert (((codegen_imp == FFEINTRIN_impCTIME_subr) ?
5222 ffecom_f2c_longint_type_node :
5223 ffecom_f2c_integer_type_node),
5224 ffecom_expr (arg1));
5225 arg2_tree = ffecom_1 (ADDR_EXPR,
5226 build_pointer_type (TREE_TYPE (arg2_tree)),
5229 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5230 arg1_len = build_tree_list (NULL_TREE, arg1_len);
5231 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
5232 TREE_CHAIN (arg1_len) = arg2_tree;
5233 TREE_CHAIN (arg1_tree) = arg1_len;
5236 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5237 ffecom_gfrt_kindtype (gfrt),
5241 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5242 ffebld_nonter_hook (expr));
5243 TREE_SIDE_EFFECTS (expr_tree) = 1;
5247 case FFEINTRIN_impIRAND:
5248 case FFEINTRIN_impRAND:
5249 /* Arg defaults to 0 (normal random case) */
5254 arg1_tree = ffecom_integer_zero_node;
5256 arg1_tree = ffecom_expr (arg1);
5257 arg1_tree = convert (ffecom_f2c_integer_type_node,
5259 arg1_tree = ffecom_1 (ADDR_EXPR,
5260 build_pointer_type (TREE_TYPE (arg1_tree)),
5262 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
5264 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5265 ffecom_gfrt_kindtype (gfrt),
5267 ((codegen_imp == FFEINTRIN_impIRAND) ?
5268 ffecom_f2c_integer_type_node :
5269 ffecom_f2c_real_type_node),
5271 dest_tree, dest, dest_used,
5273 ffebld_nonter_hook (expr));
5277 case FFEINTRIN_impFTELL_subr:
5278 case FFEINTRIN_impUMASK_subr:
5283 arg1_tree = convert (ffecom_f2c_integer_type_node,
5284 ffecom_expr (arg1));
5285 arg1_tree = ffecom_1 (ADDR_EXPR,
5286 build_pointer_type (TREE_TYPE (arg1_tree)),
5290 arg2_tree = NULL_TREE;
5292 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
5294 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5295 ffecom_gfrt_kindtype (gfrt),
5298 build_tree_list (NULL_TREE, arg1_tree),
5299 NULL_TREE, NULL, NULL, NULL_TREE,
5301 ffebld_nonter_hook (expr));
5302 if (arg2_tree != NULL_TREE) {
5303 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
5304 convert (TREE_TYPE (arg2_tree),
5310 case FFEINTRIN_impCPU_TIME:
5311 case FFEINTRIN_impSECOND_subr:
5315 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
5318 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5319 ffecom_gfrt_kindtype (gfrt),
5323 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
5324 ffebld_nonter_hook (expr));
5327 = ffecom_modify (NULL_TREE, arg1_tree,
5328 convert (TREE_TYPE (arg1_tree),
5333 case FFEINTRIN_impDTIME_subr:
5334 case FFEINTRIN_impETIME_subr:
5339 result_tree = ffecom_expr_w (NULL_TREE, arg2);
5341 arg1_tree = ffecom_ptr_to_expr (arg1);
5343 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
5344 ffecom_gfrt_kindtype (gfrt),
5347 build_tree_list (NULL_TREE, arg1_tree),
5348 NULL_TREE, NULL, NULL, NULL_TREE,
5350 ffebld_nonter_hook (expr));
5351 expr_tree = ffecom_modify (NULL_TREE, result_tree,
5352 convert (TREE_TYPE (result_tree),
5357 /* Straightforward calls of libf2c routines: */
5358 case FFEINTRIN_impABORT:
5359 case FFEINTRIN_impACCESS:
5360 case FFEINTRIN_impBESJ0:
5361 case FFEINTRIN_impBESJ1:
5362 case FFEINTRIN_impBESJN:
5363 case FFEINTRIN_impBESY0:
5364 case FFEINTRIN_impBESY1:
5365 case FFEINTRIN_impBESYN:
5366 case FFEINTRIN_impCHDIR_func:
5367 case FFEINTRIN_impCHMOD_func:
5368 case FFEINTRIN_impDATE:
5369 case FFEINTRIN_impDATE_AND_TIME:
5370 case FFEINTRIN_impDBESJ0:
5371 case FFEINTRIN_impDBESJ1:
5372 case FFEINTRIN_impDBESJN:
5373 case FFEINTRIN_impDBESY0:
5374 case FFEINTRIN_impDBESY1:
5375 case FFEINTRIN_impDBESYN:
5376 case FFEINTRIN_impDTIME_func:
5377 case FFEINTRIN_impETIME_func:
5378 case FFEINTRIN_impFGETC_func:
5379 case FFEINTRIN_impFGET_func:
5380 case FFEINTRIN_impFNUM:
5381 case FFEINTRIN_impFPUTC_func:
5382 case FFEINTRIN_impFPUT_func:
5383 case FFEINTRIN_impFSEEK:
5384 case FFEINTRIN_impFSTAT_func:
5385 case FFEINTRIN_impFTELL_func:
5386 case FFEINTRIN_impGERROR:
5387 case FFEINTRIN_impGETARG:
5388 case FFEINTRIN_impGETCWD_func:
5389 case FFEINTRIN_impGETENV:
5390 case FFEINTRIN_impGETGID:
5391 case FFEINTRIN_impGETLOG:
5392 case FFEINTRIN_impGETPID:
5393 case FFEINTRIN_impGETUID:
5394 case FFEINTRIN_impGMTIME:
5395 case FFEINTRIN_impHOSTNM_func:
5396 case FFEINTRIN_impIDATE_unix:
5397 case FFEINTRIN_impIDATE_vxt:
5398 case FFEINTRIN_impIERRNO:
5399 case FFEINTRIN_impISATTY:
5400 case FFEINTRIN_impITIME:
5401 case FFEINTRIN_impKILL_func:
5402 case FFEINTRIN_impLINK_func:
5403 case FFEINTRIN_impLNBLNK:
5404 case FFEINTRIN_impLSTAT_func:
5405 case FFEINTRIN_impLTIME:
5406 case FFEINTRIN_impMCLOCK8:
5407 case FFEINTRIN_impMCLOCK:
5408 case FFEINTRIN_impPERROR:
5409 case FFEINTRIN_impRENAME_func:
5410 case FFEINTRIN_impSECNDS:
5411 case FFEINTRIN_impSECOND_func:
5412 case FFEINTRIN_impSLEEP:
5413 case FFEINTRIN_impSRAND:
5414 case FFEINTRIN_impSTAT_func:
5415 case FFEINTRIN_impSYMLNK_func:
5416 case FFEINTRIN_impSYSTEM_CLOCK:
5417 case FFEINTRIN_impSYSTEM_func:
5418 case FFEINTRIN_impTIME8:
5419 case FFEINTRIN_impTIME_unix:
5420 case FFEINTRIN_impTIME_vxt:
5421 case FFEINTRIN_impUMASK_func:
5422 case FFEINTRIN_impUNLINK_func:
5425 case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */
5426 case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */
5427 case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */
5428 case FFEINTRIN_impNONE:
5429 case FFEINTRIN_imp: /* Hush up gcc warning. */
5430 fprintf (stderr, "No %s implementation.\n",
5431 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
5432 assert ("unimplemented intrinsic" == NULL);
5433 return error_mark_node;
5436 assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */
5438 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
5439 ffebld_right (expr));
5441 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
5442 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
5444 expr_tree, dest_tree, dest, dest_used,
5446 ffebld_nonter_hook (expr));
5448 /* See bottom of this file for f2c transforms used to determine
5449 many of the above implementations. The info seems to confuse
5450 Emacs's C mode indentation, which is why it's been moved to
5451 the bottom of this source file. */
5455 /* For power (exponentiation) where right-hand operand is type INTEGER,
5456 generate in-line code to do it the fast way (which, if the operand
5457 is a constant, might just mean a series of multiplies). */
5459 #if FFECOM_targetCURRENT == FFECOM_targetGCC
5461 ffecom_expr_power_integer_ (ffebld expr)
5463 tree l = ffecom_expr (ffebld_left (expr));
5464 tree r = ffecom_expr (ffebld_right (expr));
5465 tree ltype = TREE_TYPE (l);
5466 tree rtype = TREE_TYPE (r);
5467 tree result = NULL_TREE;
5469 if (l == error_mark_node
5470 || r == error_mark_node)
5471 return error_mark_node;
5473 if (TREE_CODE (r) == INTEGER_CST)
5475 int sgn = tree_int_cst_sgn (r);
5478 return convert (ltype, integer_one_node);
5480 if ((TREE_CODE (ltype) == INTEGER_TYPE)
5483 /* Reciprocal of integer is either 0, -1, or 1, so after
5484 calculating that (which we leave to the back end to do
5485 or not do optimally), don't bother with any multiplying. */
5487 result = ffecom_tree_divide_ (ltype,
5488 convert (ltype, integer_one_node),
5490 NULL_TREE, NULL, NULL, NULL_TREE);
5491 r = ffecom_1 (NEGATE_EXPR,
5494 if ((TREE_INT_CST_LOW (r) & 1) == 0)
5495 result = ffecom_1 (ABS_EXPR, rtype,
5499 /* Generate appropriate series of multiplies, preceded
5500 by divide if the exponent is negative. */
5506 l = ffecom_tree_divide_ (ltype,
5507 convert (ltype, integer_one_node),
5509 NULL_TREE, NULL, NULL,
5510 ffebld_nonter_hook (expr));
5511 r = ffecom_1 (NEGATE_EXPR, rtype, r);
5512 assert (TREE_CODE (r) == INTEGER_CST);
5514 if (tree_int_cst_sgn (r) < 0)
5515 { /* The "most negative" number. */
5516 r = ffecom_1 (NEGATE_EXPR, rtype,
5517 ffecom_2 (RSHIFT_EXPR, rtype,
5521 l = ffecom_2 (MULT_EXPR, ltype,
5529 if (TREE_INT_CST_LOW (r) & 1)
5531 if (result == NULL_TREE)
5534 result = ffecom_2 (MULT_EXPR, ltype,
5539 r = ffecom_2 (RSHIFT_EXPR, rtype,
5542 if (integer_zerop (r))
5544 assert (TREE_CODE (r) == INTEGER_CST);
5547 l = ffecom_2 (MULT_EXPR, ltype,
5554 /* Though rhs isn't a constant, in-line code cannot be expanded
5555 while transforming dummies
5556 because the back end cannot be easily convinced to generate
5557 stores (MODIFY_EXPR), handle temporaries, and so on before
5558 all the appropriate rtx's have been generated for things like
5559 dummy args referenced in rhs -- which doesn't happen until
5560 store_parm_decls() is called (expand_function_start, I believe,
5561 does the actual rtx-stuffing of PARM_DECLs).
5563 So, in this case, let the caller generate the call to the
5564 run-time-library function to evaluate the power for us. */
5566 if (ffecom_transform_only_dummies_)
5569 /* Right-hand operand not a constant, expand in-line code to figure
5570 out how to do the multiplies, &c.
5572 The returned expression is expressed this way in GNU C, where l and
5575 ({ typeof (r) rtmp = r;
5576 typeof (l) ltmp = l;
5583 if ((basetypeof (l) == basetypeof (int))
5586 result = ((typeof (l)) 1) / ltmp;
5587 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5593 if ((basetypeof (l) != basetypeof (int))
5596 ltmp = ((typeof (l)) 1) / ltmp;
5600 rtmp = -(rtmp >> 1);
5608 if ((rtmp >>= 1) == 0)
5617 Note that some of the above is compile-time collapsable, such as
5618 the first part of the if statements that checks the base type of
5619 l against int. The if statements are phrased that way to suggest
5620 an easy way to generate the if/else constructs here, knowing that
5621 the back end should (and probably does) eliminate the resulting
5622 dead code (either the int case or the non-int case), something
5623 it couldn't do without the redundant phrasing, requiring explicit
5624 dead-code elimination here, which would be kind of difficult to
5631 tree basetypeof_l_is_int;
5636 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
5638 se = expand_start_stmt_expr ();
5640 ffecom_start_compstmt ();
5643 rtmp = ffecom_make_tempvar ("power_r", rtype,
5644 FFETARGET_charactersizeNONE, -1);
5645 ltmp = ffecom_make_tempvar ("power_l", ltype,
5646 FFETARGET_charactersizeNONE, -1);
5647 result = ffecom_make_tempvar ("power_res", ltype,
5648 FFETARGET_charactersizeNONE, -1);
5649 if (TREE_CODE (ltype) == COMPLEX_TYPE
5650 || TREE_CODE (ltype) == RECORD_TYPE)
5651 divide = ffecom_make_tempvar ("power_div", ltype,
5652 FFETARGET_charactersizeNONE, -1);
5659 hook = ffebld_nonter_hook (expr);
5661 assert (TREE_CODE (hook) == TREE_VEC);
5662 assert (TREE_VEC_LENGTH (hook) == 4);
5663 rtmp = TREE_VEC_ELT (hook, 0);
5664 ltmp = TREE_VEC_ELT (hook, 1);
5665 result = TREE_VEC_ELT (hook, 2);
5666 divide = TREE_VEC_ELT (hook, 3);
5667 if (TREE_CODE (ltype) == COMPLEX_TYPE
5668 || TREE_CODE (ltype) == RECORD_TYPE)
5675 expand_expr_stmt (ffecom_modify (void_type_node,
5678 expand_expr_stmt (ffecom_modify (void_type_node,
5681 expand_start_cond (ffecom_truth_value
5682 (ffecom_2 (EQ_EXPR, integer_type_node,
5684 convert (rtype, integer_zero_node))),
5686 expand_expr_stmt (ffecom_modify (void_type_node,
5688 convert (ltype, integer_one_node)));
5689 expand_start_else ();
5690 if (! integer_zerop (basetypeof_l_is_int))
5692 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
5695 integer_zero_node)),
5697 expand_expr_stmt (ffecom_modify (void_type_node,
5701 convert (ltype, integer_one_node),
5703 NULL_TREE, NULL, NULL,
5705 expand_start_cond (ffecom_truth_value
5706 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5707 ffecom_2 (LT_EXPR, integer_type_node,
5710 integer_zero_node)),
5711 ffecom_2 (EQ_EXPR, integer_type_node,
5712 ffecom_2 (BIT_AND_EXPR,
5714 ffecom_1 (NEGATE_EXPR,
5720 integer_zero_node)))),
5722 expand_expr_stmt (ffecom_modify (void_type_node,
5724 ffecom_1 (NEGATE_EXPR,
5728 expand_start_else ();
5730 expand_expr_stmt (ffecom_modify (void_type_node,
5732 convert (ltype, integer_one_node)));
5733 expand_start_cond (ffecom_truth_value
5734 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
5735 ffecom_truth_value_invert
5736 (basetypeof_l_is_int),
5737 ffecom_2 (LT_EXPR, integer_type_node,
5740 integer_zero_node)))),
5742 expand_expr_stmt (ffecom_modify (void_type_node,
5746 convert (ltype, integer_one_node),
5748 NULL_TREE, NULL, NULL,
5750 expand_expr_stmt (ffecom_modify (void_type_node,
5752 ffecom_1 (NEGATE_EXPR, rtype,
5754 expand_start_cond (ffecom_truth_value
5755 (ffecom_2 (LT_EXPR, integer_type_node,
5757 convert (rtype, integer_zero_node))),
5759 expand_expr_stmt (ffecom_modify (void_type_node,
5761 ffecom_1 (NEGATE_EXPR, rtype,
5762 ffecom_2 (RSHIFT_EXPR,
5765 integer_one_node))));
5766 expand_expr_stmt (ffecom_modify (void_type_node,
5768 ffecom_2 (MULT_EXPR, ltype,
5773 expand_start_loop (1);
5774 expand_start_cond (ffecom_truth_value
5775 (ffecom_2 (BIT_AND_EXPR, rtype,
5777 convert (rtype, integer_one_node))),
5779 expand_expr_stmt (ffecom_modify (void_type_node,
5781 ffecom_2 (MULT_EXPR, ltype,
5785 expand_exit_loop_if_false (NULL,
5787 (ffecom_modify (rtype,
5789 ffecom_2 (RSHIFT_EXPR,
5792 integer_one_node))));
5793 expand_expr_stmt (ffecom_modify (void_type_node,
5795 ffecom_2 (MULT_EXPR, ltype,
5800 if (!integer_zerop (basetypeof_l_is_int))
5802 expand_expr_stmt (result);
5804 t = ffecom_end_compstmt ();
5806 result = expand_end_stmt_expr (se);
5808 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5810 if (TREE_CODE (t) == BLOCK)
5812 /* Make a BIND_EXPR for the BLOCK already made. */
5813 result = build (BIND_EXPR, TREE_TYPE (result),
5814 NULL_TREE, result, t);
5815 /* Remove the block from the tree at this point.
5816 It gets put back at the proper place
5817 when the BIND_EXPR is expanded. */
5828 /* ffecom_expr_transform_ -- Transform symbols in expr
5830 ffebld expr; // FFE expression.
5831 ffecom_expr_transform_ (expr);
5833 Recursive descent on expr while transforming any untransformed SYMTERs. */
5835 #if FFECOM_targetCURRENT == FFECOM_targetGCC
5837 ffecom_expr_transform_ (ffebld expr)
5842 tail_recurse: /* :::::::::::::::::::: */
5847 switch (ffebld_op (expr))
5849 case FFEBLD_opSYMTER:
5850 s = ffebld_symter (expr);
5851 t = ffesymbol_hook (s).decl_tree;
5852 if ((t == NULL_TREE)
5853 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
5854 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
5855 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
5857 s = ffecom_sym_transform_ (s);
5858 t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy,
5861 break; /* Ok if (t == NULL) here. */
5864 ffecom_expr_transform_ (ffebld_head (expr));
5865 expr = ffebld_trail (expr);
5866 goto tail_recurse; /* :::::::::::::::::::: */
5872 switch (ffebld_arity (expr))
5875 ffecom_expr_transform_ (ffebld_left (expr));
5876 expr = ffebld_right (expr);
5877 goto tail_recurse; /* :::::::::::::::::::: */
5880 expr = ffebld_left (expr);
5881 goto tail_recurse; /* :::::::::::::::::::: */
5891 /* Make a type based on info in live f2c.h file. */
5893 #if FFECOM_targetCURRENT == FFECOM_targetGCC
5895 ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
5899 case FFECOM_f2ccodeCHAR:
5900 *type = make_signed_type (CHAR_TYPE_SIZE);
5903 case FFECOM_f2ccodeSHORT:
5904 *type = make_signed_type (SHORT_TYPE_SIZE);
5907 case FFECOM_f2ccodeINT:
5908 *type = make_signed_type (INT_TYPE_SIZE);
5911 case FFECOM_f2ccodeLONG:
5912 *type = make_signed_type (LONG_TYPE_SIZE);
5915 case FFECOM_f2ccodeLONGLONG:
5916 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
5919 case FFECOM_f2ccodeCHARPTR:
5920 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
5921 ? signed_char_type_node
5922 : unsigned_char_type_node);
5925 case FFECOM_f2ccodeFLOAT:
5926 *type = make_node (REAL_TYPE);
5927 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
5928 layout_type (*type);
5931 case FFECOM_f2ccodeDOUBLE:
5932 *type = make_node (REAL_TYPE);
5933 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
5934 layout_type (*type);
5937 case FFECOM_f2ccodeLONGDOUBLE:
5938 *type = make_node (REAL_TYPE);
5939 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
5940 layout_type (*type);
5943 case FFECOM_f2ccodeTWOREALS:
5944 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
5947 case FFECOM_f2ccodeTWODOUBLEREALS:
5948 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
5952 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
5953 *type = error_mark_node;
5957 pushdecl (build_decl (TYPE_DECL,
5958 ffecom_get_invented_identifier ("__g77_f2c_%s", name),
5963 #if FFECOM_targetCURRENT == FFECOM_targetGCC
5964 /* Set the f2c list-directed-I/O code for whatever (integral) type has the
5968 ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
5974 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
5975 if ((t = ffecom_tree_type[bt][j]) != NULL_TREE
5976 && compare_tree_int (TYPE_SIZE (t), size) == 0)
5978 assert (code != -1);
5979 ffecom_f2c_typecode_[bt][j] = code;
5985 /* Finish up globals after doing all program units in file
5987 Need to handle only uninitialized COMMON areas. */
5989 #if FFECOM_targetCURRENT == FFECOM_targetGCC
5991 ffecom_finish_global_ (ffeglobal global)
5997 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
6000 if (ffeglobal_common_init (global))
6003 cbt = ffeglobal_hook (global);
6004 if ((cbt == NULL_TREE)
6005 || !ffeglobal_common_have_size (global))
6006 return global; /* No need to make common, never ref'd. */
6008 DECL_EXTERNAL (cbt) = 0;
6010 /* Give the array a size now. */
6012 size = build_int_2 ((ffeglobal_common_size (global)
6013 + ffeglobal_common_pad (global)) - 1,
6016 cbtype = TREE_TYPE (cbt);
6017 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
6020 if (!TREE_TYPE (size))
6021 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
6022 layout_type (cbtype);
6024 cbt = start_decl (cbt, FALSE);
6025 assert (cbt == ffeglobal_hook (global));
6027 finish_decl (cbt, NULL_TREE, FALSE);
6033 /* Finish up any untransformed symbols. */
6035 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6037 ffecom_finish_symbol_transform_ (ffesymbol s)
6039 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
6042 /* It's easy to know to transform an untransformed symbol, to make sure
6043 we put out debugging info for it. But COMMON variables, unlike
6044 EQUIVALENCE ones, aren't given declarations in addition to the
6045 tree expressions that specify offsets, because COMMON variables
6046 can be referenced in the outer scope where only dummy arguments
6047 (PARM_DECLs) should really be seen. To be safe, just don't do any
6048 VAR_DECLs for COMMON variables when we transform them for real
6049 use, and therefore we do all the VAR_DECL creating here. */
6051 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
6053 if (ffesymbol_kind (s) != FFEINFO_kindNONE
6054 || (ffesymbol_where (s) != FFEINFO_whereNONE
6055 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
6056 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
6057 /* Not transformed, and not CHARACTER*(*), and not a dummy
6058 argument, which can happen only if the entry point names
6059 it "rides in on" are all invalidated for other reasons. */
6060 s = ffecom_sym_transform_ (s);
6063 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
6064 && (ffesymbol_hook (s).decl_tree != error_mark_node))
6066 /* This isn't working, at least for dbxout. The .s file looks
6067 okay to me (burley), but in gdb 4.9 at least, the variables
6068 appear to reside somewhere outside of the common area, so
6069 it doesn't make sense to mislead anyone by generating the info
6070 on those variables until this is fixed. NOTE: Same problem
6071 with EQUIVALENCE, sadly...see similar #if later. */
6072 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
6073 ffesymbol_storage (s));
6080 /* Append underscore(s) to name before calling get_identifier. "us"
6081 is nonzero if the name already contains an underscore and thus
6082 needs two underscores appended. */
6084 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6086 ffecom_get_appended_identifier_ (char us, const char *name)
6092 newname = xmalloc ((i = strlen (name)) + 1
6093 + ffe_is_underscoring ()
6095 memcpy (newname, name, i);
6097 newname[i + us] = '_';
6098 newname[i + 1 + us] = '\0';
6099 id = get_identifier (newname);
6107 /* Decide whether to append underscore to name before calling
6110 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6112 ffecom_get_external_identifier_ (ffesymbol s)
6115 const char *name = ffesymbol_text (s);
6117 /* If name is a built-in name, just return it as is. */
6119 if (!ffe_is_underscoring ()
6120 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
6121 #if FFETARGET_isENFORCED_MAIN_NAME
6122 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
6124 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
6126 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
6127 return get_identifier (name);
6129 us = ffe_is_second_underscore ()
6130 ? (strchr (name, '_') != NULL)
6133 return ffecom_get_appended_identifier_ (us, name);
6137 /* Decide whether to append underscore to internal name before calling
6140 This is for non-external, top-function-context names only. Transform
6141 identifier so it doesn't conflict with the transformed result
6142 of using a _different_ external name. E.g. if "CALL FOO" is
6143 transformed into "FOO_();", then the variable in "FOO_ = 3"
6144 must be transformed into something that does not conflict, since
6145 these two things should be independent.
6147 The transformation is as follows. If the name does not contain
6148 an underscore, there is no possible conflict, so just return.
6149 If the name does contain an underscore, then transform it just
6150 like we transform an external identifier. */
6152 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6154 ffecom_get_identifier_ (const char *name)
6156 /* If name does not contain an underscore, just return it as is. */
6158 if (!ffe_is_underscoring ()
6159 || (strchr (name, '_') == NULL))
6160 return get_identifier (name);
6162 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6167 /* ffecom_gen_sfuncdef_ -- Generate definition of statement function
6170 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6171 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6172 ffesymbol_kindtype(s));
6174 Call after setting up containing function and getting trees for all
6177 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6179 ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
6181 ffebld expr = ffesymbol_sfexpr (s);
6185 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
6186 static bool recurse = FALSE;
6187 int old_lineno = lineno;
6188 const char *old_input_filename = input_filename;
6190 ffecom_nested_entry_ = s;
6192 /* For now, we don't have a handy pointer to where the sfunc is actually
6193 defined, though that should be easy to add to an ffesymbol. (The
6194 token/where info available might well point to the place where the type
6195 of the sfunc is declared, especially if that precedes the place where
6196 the sfunc itself is defined, which is typically the case.) We should
6197 put out a null pointer rather than point somewhere wrong, but I want to
6198 see how it works at this point. */
6200 input_filename = ffesymbol_where_filename (s);
6201 lineno = ffesymbol_where_filelinenum (s);
6203 /* Pretransform the expression so any newly discovered things belong to the
6204 outer program unit, not to the statement function. */
6206 ffecom_expr_transform_ (expr);
6208 /* Make sure no recursive invocation of this fn (a specific case of failing
6209 to pretransform an sfunc's expression, i.e. where its expression
6210 references another untransformed sfunc) happens. */
6215 push_f_function_context ();
6218 type = void_type_node;
6221 type = ffecom_tree_type[bt][kt];
6222 if (type == NULL_TREE)
6223 type = integer_type_node; /* _sym_exec_transition reports
6227 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
6228 build_function_type (type, NULL_TREE),
6229 1, /* nested/inline */
6230 0); /* TREE_PUBLIC */
6232 /* We don't worry about COMPLEX return values here, because this is
6233 entirely internal to our code, and gcc has the ability to return COMPLEX
6234 directly as a value. */
6237 { /* Prepend arg for where result goes. */
6240 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
6242 result = ffecom_get_invented_identifier ("__g77_%s", "result");
6244 ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */
6246 type = build_pointer_type (type);
6247 result = build_decl (PARM_DECL, result, type);
6249 push_parm_decl (result);
6252 result = NULL_TREE; /* Not ref'd if !charfunc. */
6254 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
6256 store_parm_decls (0);
6258 ffecom_start_compstmt ();
6264 ffetargetCharacterSize sz = ffesymbol_size (s);
6267 result_length = build_int_2 (sz, 0);
6268 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
6270 ffecom_prepare_let_char_ (sz, expr);
6272 ffecom_prepare_end ();
6274 ffecom_let_char_ (result, result_length, sz, expr);
6275 expand_null_return ();
6279 ffecom_prepare_expr (expr);
6281 ffecom_prepare_end ();
6283 expand_return (ffecom_modify (NULL_TREE,
6284 DECL_RESULT (current_function_decl),
6285 ffecom_expr (expr)));
6289 ffecom_end_compstmt ();
6291 func = current_function_decl;
6292 finish_function (1);
6294 pop_f_function_context ();
6298 lineno = old_lineno;
6299 input_filename = old_input_filename;
6301 ffecom_nested_entry_ = NULL;
6308 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6310 ffecom_gfrt_args_ (ffecomGfrt ix)
6312 return ffecom_gfrt_argstring_[ix];
6316 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6318 ffecom_gfrt_tree_ (ffecomGfrt ix)
6320 if (ffecom_gfrt_[ix] == NULL_TREE)
6321 ffecom_make_gfrt_ (ix);
6323 return ffecom_1 (ADDR_EXPR,
6324 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
6329 /* Return initialize-to-zero expression for this VAR_DECL. */
6331 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6332 /* A somewhat evil way to prevent the garbage collector
6333 from collecting 'tree' structures. */
6334 #define NUM_TRACKED_CHUNK 63
6335 static struct tree_ggc_tracker
6337 struct tree_ggc_tracker *next;
6338 tree trees[NUM_TRACKED_CHUNK];
6339 } *tracker_head = NULL;
6342 mark_tracker_head (void *arg)
6344 struct tree_ggc_tracker *head;
6347 for (head = * (struct tree_ggc_tracker **) arg;
6352 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6353 ggc_mark_tree (head->trees[i]);
6358 ffecom_save_tree_forever (tree t)
6361 if (tracker_head != NULL)
6362 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
6363 if (tracker_head->trees[i] == NULL)
6365 tracker_head->trees[i] = t;
6370 /* Need to allocate a new block. */
6371 struct tree_ggc_tracker *old_head = tracker_head;
6373 tracker_head = ggc_alloc (sizeof (*tracker_head));
6374 tracker_head->next = old_head;
6375 tracker_head->trees[0] = t;
6376 for (i = 1; i < NUM_TRACKED_CHUNK; i++)
6377 tracker_head->trees[i] = NULL;
6382 ffecom_init_zero_ (tree decl)
6385 int incremental = TREE_STATIC (decl);
6386 tree type = TREE_TYPE (decl);
6390 make_decl_rtl (decl, NULL);
6391 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
6394 if ((TREE_CODE (type) != ARRAY_TYPE)
6395 && (TREE_CODE (type) != RECORD_TYPE)
6396 && (TREE_CODE (type) != UNION_TYPE)
6398 init = convert (type, integer_zero_node);
6399 else if (!incremental)
6401 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
6402 TREE_CONSTANT (init) = 1;
6403 TREE_STATIC (init) = 1;
6407 assemble_zeros (int_size_in_bytes (type));
6408 init = error_mark_node;
6415 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6417 ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
6423 switch (ffebld_op (arg))
6425 case FFEBLD_opCONTER: /* For F90, check 0-length. */
6426 if (ffetarget_length_character1
6427 (ffebld_constant_character1
6428 (ffebld_conter (arg))) == 0)
6430 *maybe_tree = integer_zero_node;
6431 return convert (tree_type, integer_zero_node);
6434 *maybe_tree = integer_one_node;
6435 expr_tree = build_int_2 (*ffetarget_text_character1
6436 (ffebld_constant_character1
6437 (ffebld_conter (arg))),
6439 TREE_TYPE (expr_tree) = tree_type;
6442 case FFEBLD_opSYMTER:
6443 case FFEBLD_opARRAYREF:
6444 case FFEBLD_opFUNCREF:
6445 case FFEBLD_opSUBSTR:
6446 ffecom_char_args_ (&expr_tree, &length_tree, arg);
6448 if ((expr_tree == error_mark_node)
6449 || (length_tree == error_mark_node))
6451 *maybe_tree = error_mark_node;
6452 return error_mark_node;
6455 if (integer_zerop (length_tree))
6457 *maybe_tree = integer_zero_node;
6458 return convert (tree_type, integer_zero_node);
6462 = ffecom_1 (INDIRECT_REF,
6463 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6466 = ffecom_2 (ARRAY_REF,
6467 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
6470 expr_tree = convert (tree_type, expr_tree);
6472 if (TREE_CODE (length_tree) == INTEGER_CST)
6473 *maybe_tree = integer_one_node;
6474 else /* Must check length at run time. */
6476 = ffecom_truth_value
6477 (ffecom_2 (GT_EXPR, integer_type_node,
6479 ffecom_f2c_ftnlen_zero_node));
6482 case FFEBLD_opPAREN:
6483 case FFEBLD_opCONVERT:
6484 if (ffeinfo_size (ffebld_info (arg)) == 0)
6486 *maybe_tree = integer_zero_node;
6487 return convert (tree_type, integer_zero_node);
6489 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6492 case FFEBLD_opCONCATENATE:
6499 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
6501 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
6503 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
6506 expr_tree = ffecom_3 (COND_EXPR, tree_type,
6514 assert ("bad op in ICHAR" == NULL);
6515 return error_mark_node;
6520 /* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6524 length_arg = ffecom_intrinsic_len_ (expr);
6526 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6527 subexpressions by constructing the appropriate tree for the
6528 length-of-character-text argument in a calling sequence. */
6530 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6532 ffecom_intrinsic_len_ (ffebld expr)
6534 ffetargetCharacter1 val;
6537 switch (ffebld_op (expr))
6539 case FFEBLD_opCONTER:
6540 val = ffebld_constant_character1 (ffebld_conter (expr));
6541 length = build_int_2 (ffetarget_length_character1 (val), 0);
6542 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6545 case FFEBLD_opSYMTER:
6547 ffesymbol s = ffebld_symter (expr);
6550 item = ffesymbol_hook (s).decl_tree;
6551 if (item == NULL_TREE)
6553 s = ffecom_sym_transform_ (s);
6554 item = ffesymbol_hook (s).decl_tree;
6556 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
6558 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
6559 length = ffesymbol_hook (s).length_tree;
6562 length = build_int_2 (ffesymbol_size (s), 0);
6563 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6566 else if (item == error_mark_node)
6567 length = error_mark_node;
6568 else /* FFEINFO_kindFUNCTION: */
6573 case FFEBLD_opARRAYREF:
6574 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6577 case FFEBLD_opSUBSTR:
6581 ffebld thing = ffebld_right (expr);
6585 assert (ffebld_op (thing) == FFEBLD_opITEM);
6586 start = ffebld_head (thing);
6587 thing = ffebld_trail (thing);
6588 assert (ffebld_trail (thing) == NULL);
6589 end = ffebld_head (thing);
6591 length = ffecom_intrinsic_len_ (ffebld_left (expr));
6593 if (length == error_mark_node)
6602 length = convert (ffecom_f2c_ftnlen_type_node,
6608 start_tree = convert (ffecom_f2c_ftnlen_type_node,
6609 ffecom_expr (start));
6611 if (start_tree == error_mark_node)
6613 length = error_mark_node;
6619 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6620 ffecom_f2c_ftnlen_one_node,
6621 ffecom_2 (MINUS_EXPR,
6622 ffecom_f2c_ftnlen_type_node,
6628 end_tree = convert (ffecom_f2c_ftnlen_type_node,
6631 if (end_tree == error_mark_node)
6633 length = error_mark_node;
6637 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6638 ffecom_f2c_ftnlen_one_node,
6639 ffecom_2 (MINUS_EXPR,
6640 ffecom_f2c_ftnlen_type_node,
6641 end_tree, start_tree));
6647 case FFEBLD_opCONCATENATE:
6649 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
6650 ffecom_intrinsic_len_ (ffebld_left (expr)),
6651 ffecom_intrinsic_len_ (ffebld_right (expr)));
6654 case FFEBLD_opFUNCREF:
6655 case FFEBLD_opCONVERT:
6656 length = build_int_2 (ffebld_size (expr), 0);
6657 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
6661 assert ("bad op for single char arg expr" == NULL);
6662 length = ffecom_f2c_ftnlen_zero_node;
6666 assert (length != NULL_TREE);
6672 /* Handle CHARACTER assignments.
6674 Generates code to do the assignment. Used by ordinary assignment
6675 statement handler ffecom_let_stmt and by statement-function
6676 handler to generate code for a statement function. */
6678 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6680 ffecom_let_char_ (tree dest_tree, tree dest_length,
6681 ffetargetCharacterSize dest_size, ffebld source)
6683 ffecomConcatList_ catlist;
6688 if ((dest_tree == error_mark_node)
6689 || (dest_length == error_mark_node))
6692 assert (dest_tree != NULL_TREE);
6693 assert (dest_length != NULL_TREE);
6695 /* Source might be an opCONVERT, which just means it is a different size
6696 than the destination. Since the underlying implementation here handles
6697 that (directly or via the s_copy or s_cat run-time-library functions),
6698 we don't need the "convenience" of an opCONVERT that tells us to
6699 truncate or blank-pad, particularly since the resulting implementation
6700 would probably be slower than otherwise. */
6702 while (ffebld_op (source) == FFEBLD_opCONVERT)
6703 source = ffebld_left (source);
6705 catlist = ffecom_concat_list_new_ (source, dest_size);
6706 switch (ffecom_concat_list_count_ (catlist))
6708 case 0: /* Shouldn't happen, but in case it does... */
6709 ffecom_concat_list_kill_ (catlist);
6710 source_tree = null_pointer_node;
6711 source_length = ffecom_f2c_ftnlen_zero_node;
6712 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6713 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6714 TREE_CHAIN (TREE_CHAIN (expr_tree))
6715 = build_tree_list (NULL_TREE, dest_length);
6716 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6717 = build_tree_list (NULL_TREE, source_length);
6719 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6720 TREE_SIDE_EFFECTS (expr_tree) = 1;
6722 expand_expr_stmt (expr_tree);
6726 case 1: /* The (fairly) easy case. */
6727 ffecom_char_args_ (&source_tree, &source_length,
6728 ffecom_concat_list_expr_ (catlist, 0));
6729 ffecom_concat_list_kill_ (catlist);
6730 assert (source_tree != NULL_TREE);
6731 assert (source_length != NULL_TREE);
6733 if ((source_tree == error_mark_node)
6734 || (source_length == error_mark_node))
6740 = ffecom_1 (INDIRECT_REF,
6741 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6745 = ffecom_2 (ARRAY_REF,
6746 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6751 = ffecom_1 (INDIRECT_REF,
6752 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6756 = ffecom_2 (ARRAY_REF,
6757 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6762 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
6764 expand_expr_stmt (expr_tree);
6769 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6770 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
6771 TREE_CHAIN (TREE_CHAIN (expr_tree))
6772 = build_tree_list (NULL_TREE, dest_length);
6773 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6774 = build_tree_list (NULL_TREE, source_length);
6776 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
6777 TREE_SIDE_EFFECTS (expr_tree) = 1;
6779 expand_expr_stmt (expr_tree);
6783 default: /* Must actually concatenate things. */
6787 /* Heavy-duty concatenation. */
6790 int count = ffecom_concat_list_count_ (catlist);
6802 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
6803 FFETARGET_charactersizeNONE, count, TRUE);
6804 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
6805 FFETARGET_charactersizeNONE,
6811 hook = ffebld_nonter_hook (source);
6813 assert (TREE_CODE (hook) == TREE_VEC);
6814 assert (TREE_VEC_LENGTH (hook) == 2);
6815 length_array = lengths = TREE_VEC_ELT (hook, 0);
6816 item_array = items = TREE_VEC_ELT (hook, 1);
6820 for (i = 0; i < count; ++i)
6822 ffecom_char_args_ (&citem, &clength,
6823 ffecom_concat_list_expr_ (catlist, i));
6824 if ((citem == error_mark_node)
6825 || (clength == error_mark_node))
6827 ffecom_concat_list_kill_ (catlist);
6832 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
6833 ffecom_modify (void_type_node,
6834 ffecom_2 (ARRAY_REF,
6835 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
6837 build_int_2 (i, 0)),
6841 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
6842 ffecom_modify (void_type_node,
6843 ffecom_2 (ARRAY_REF,
6844 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
6846 build_int_2 (i, 0)),
6851 expr_tree = build_tree_list (NULL_TREE, dest_tree);
6852 TREE_CHAIN (expr_tree)
6853 = build_tree_list (NULL_TREE,
6854 ffecom_1 (ADDR_EXPR,
6855 build_pointer_type (TREE_TYPE (items)),
6857 TREE_CHAIN (TREE_CHAIN (expr_tree))
6858 = build_tree_list (NULL_TREE,
6859 ffecom_1 (ADDR_EXPR,
6860 build_pointer_type (TREE_TYPE (lengths)),
6862 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
6865 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
6866 convert (ffecom_f2c_ftnlen_type_node,
6867 build_int_2 (count, 0))));
6868 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
6869 = build_tree_list (NULL_TREE, dest_length);
6871 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
6872 TREE_SIDE_EFFECTS (expr_tree) = 1;
6874 expand_expr_stmt (expr_tree);
6877 ffecom_concat_list_kill_ (catlist);
6881 /* ffecom_make_gfrt_ -- Make initial info for run-time routine
6884 ffecom_make_gfrt_(ix);
6886 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6887 for the indicated run-time routine (ix). */
6889 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6891 ffecom_make_gfrt_ (ffecomGfrt ix)
6896 switch (ffecom_gfrt_type_[ix])
6898 case FFECOM_rttypeVOID_:
6899 ttype = void_type_node;
6902 case FFECOM_rttypeVOIDSTAR_:
6903 ttype = TREE_TYPE (null_pointer_node); /* `void *'. */
6906 case FFECOM_rttypeFTNINT_:
6907 ttype = ffecom_f2c_ftnint_type_node;
6910 case FFECOM_rttypeINTEGER_:
6911 ttype = ffecom_f2c_integer_type_node;
6914 case FFECOM_rttypeLONGINT_:
6915 ttype = ffecom_f2c_longint_type_node;
6918 case FFECOM_rttypeLOGICAL_:
6919 ttype = ffecom_f2c_logical_type_node;
6922 case FFECOM_rttypeREAL_F2C_:
6923 ttype = double_type_node;
6926 case FFECOM_rttypeREAL_GNU_:
6927 ttype = float_type_node;
6930 case FFECOM_rttypeCOMPLEX_F2C_:
6931 ttype = void_type_node;
6934 case FFECOM_rttypeCOMPLEX_GNU_:
6935 ttype = ffecom_f2c_complex_type_node;
6938 case FFECOM_rttypeDOUBLE_:
6939 ttype = double_type_node;
6942 case FFECOM_rttypeDOUBLEREAL_:
6943 ttype = ffecom_f2c_doublereal_type_node;
6946 case FFECOM_rttypeDBLCMPLX_F2C_:
6947 ttype = void_type_node;
6950 case FFECOM_rttypeDBLCMPLX_GNU_:
6951 ttype = ffecom_f2c_doublecomplex_type_node;
6954 case FFECOM_rttypeCHARACTER_:
6955 ttype = void_type_node;
6960 assert ("bad rttype" == NULL);
6964 ttype = build_function_type (ttype, NULL_TREE);
6965 t = build_decl (FUNCTION_DECL,
6966 get_identifier (ffecom_gfrt_name_[ix]),
6968 DECL_EXTERNAL (t) = 1;
6969 TREE_READONLY (t) = ffecom_gfrt_const_[ix] ? 1 : 0;
6970 TREE_PUBLIC (t) = 1;
6971 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
6973 /* Sanity check: A function that's const cannot be volatile. */
6975 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_volatile_[ix] : 1);
6977 /* Sanity check: A function that's const cannot return complex. */
6979 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_complex_[ix] : 1);
6981 t = start_decl (t, TRUE);
6983 finish_decl (t, NULL_TREE, TRUE);
6985 ffecom_gfrt_[ix] = t;
6989 /* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
6991 #if FFECOM_targetCURRENT == FFECOM_targetGCC
6993 ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
6995 ffesymbol s = ffestorag_symbol (st);
6997 if (ffesymbol_namelisted (s))
6998 ffecom_member_namelisted_ = TRUE;
7002 /* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
7003 the member so debugger will see it. Otherwise nobody should be
7004 referencing the member. */
7006 #if FFECOM_targetCURRENT == FFECOM_targetGCC
7008 ffecom_member_phase2_ (ffestorag mst, ffestorag st)
7016 || ((mt = ffestorag_hook (mst)) == NULL)
7017 || (mt == error_mark_node))
7021 || ((s = ffestorag_symbol (st)) == NULL))
7024 type = ffecom_type_localvar_ (s,
7025 ffesymbol_basictype (s),
7026 ffesymbol_kindtype (s));
7027 if (type == error_mark_node)
7030 t = build_decl (VAR_DECL,
7031 ffecom_get_identifier_ (ffesymbol_text (s)),
7034 TREE_STATIC (t) = TREE_STATIC (mt);
7035 DECL_INITIAL (t) = NULL_TREE;
7036 TREE_ASM_WRITTEN (t) = 1;
7040 gen_rtx (MEM, TYPE_MODE (type),
7041 plus_constant (XEXP (DECL_RTL (mt), 0),
7042 ffestorag_modulo (mst)
7043 + ffestorag_offset (st)
7044 - ffestorag_offset (mst))));
7046 t = start_decl (t, FALSE);
7048 finish_decl (t, NULL_TREE, FALSE);
7052 /* Prepare source expression for assignment into a destination perhaps known
7053 to be of a specific size. */
7056 ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
7058 ffecomConcatList_ catlist;
7063 tree tempvar = NULL_TREE;
7065 while (ffebld_op (source) == FFEBLD_opCONVERT)
7066 source = ffebld_left (source);
7068 catlist = ffecom_concat_list_new_ (source, dest_size);
7069 count = ffecom_concat_list_count_ (catlist);
7074 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
7075 FFETARGET_charactersizeNONE, count);
7077 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
7078 FFETARGET_charactersizeNONE, count);
7080 tempvar = make_tree_vec (2);
7081 TREE_VEC_ELT (tempvar, 0) = ltmp;
7082 TREE_VEC_ELT (tempvar, 1) = itmp;
7085 for (i = 0; i < count; ++i)
7086 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
7088 ffecom_concat_list_kill_ (catlist);
7092 ffebld_nonter_set_hook (source, tempvar);
7093 current_binding_level->prep_state = 1;
7097 /* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
7099 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
7100 (which generates their trees) and then their trees get push_parm_decl'd.
7102 The second arg is TRUE if the dummies are for a statement function, in
7103 which case lengths are not pushed for character arguments (since they are
7104 always known by both the caller and the callee, though the code allows
7105 for someday permitting CHAR*(*) stmtfunc dummies). */
7107 #if FFECOM_targetCURRENT == FFECOM_targetGCC
7109 ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
7116 ffecom_transform_only_dummies_ = TRUE;
7118 /* First push the parms corresponding to actual dummy "contents". */
7120 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7122 dummy = ffebld_head (dumlist);
7123 switch (ffebld_op (dummy))
7127 continue; /* Forget alternate returns. */
7132 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
7133 s = ffebld_symter (dummy);
7134 parm = ffesymbol_hook (s).decl_tree;
7135 if (parm == NULL_TREE)
7137 s = ffecom_sym_transform_ (s);
7138 parm = ffesymbol_hook (s).decl_tree;
7139 assert (parm != NULL_TREE);
7141 if (parm != error_mark_node)
7142 push_parm_decl (parm);
7145 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
7147 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
7149 dummy = ffebld_head (dumlist);
7150 switch (ffebld_op (dummy))
7154 continue; /* Forget alternate returns, they mean
7160 s = ffebld_symter (dummy);
7161 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
7162 continue; /* Only looking for CHARACTER arguments. */
7163 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
7164 continue; /* Stmtfunc arg with known size needs no
7166 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
7167 continue; /* Only looking for variables and arrays. */
7168 parm = ffesymbol_hook (s).length_tree;
7169 assert (parm != NULL_TREE);
7170 if (parm != error_mark_node)
7171 push_parm_decl (parm);
7174 ffecom_transform_only_dummies_ = FALSE;
7178 /* ffecom_start_progunit_ -- Beginning of program unit
7180 Does GNU back end stuff necessary to teach it about the start of its
7181 equivalent of a Fortran program unit. */
7183 #if FFECOM_targetCURRENT == FFECOM_targetGCC
7185 ffecom_start_progunit_ ()
7187 ffesymbol fn = ffecom_primary_entry_;
7189 tree id; /* Identifier (name) of function. */
7190 tree type; /* Type of function. */
7191 tree result; /* Result of function. */
7192 ffeinfoBasictype bt;
7196 ffeglobalType egt = FFEGLOBAL_type;
7199 bool altentries = (ffecom_num_entrypoints_ != 0);
7202 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
7203 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
7204 bool main_program = FALSE;
7205 int old_lineno = lineno;
7206 const char *old_input_filename = input_filename;
7208 assert (fn != NULL);
7209 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
7211 input_filename = ffesymbol_where_filename (fn);
7212 lineno = ffesymbol_where_filelinenum (fn);
7214 switch (ffecom_primary_entry_kind_)
7216 case FFEINFO_kindPROGRAM:
7217 main_program = TRUE;
7218 gt = FFEGLOBAL_typeMAIN;
7219 bt = FFEINFO_basictypeNONE;
7220 kt = FFEINFO_kindtypeNONE;
7221 type = ffecom_tree_fun_type_void;
7226 case FFEINFO_kindBLOCKDATA:
7227 gt = FFEGLOBAL_typeBDATA;
7228 bt = FFEINFO_basictypeNONE;
7229 kt = FFEINFO_kindtypeNONE;
7230 type = ffecom_tree_fun_type_void;
7235 case FFEINFO_kindFUNCTION:
7236 gt = FFEGLOBAL_typeFUNC;
7237 egt = FFEGLOBAL_typeEXT;
7238 bt = ffesymbol_basictype (fn);
7239 kt = ffesymbol_kindtype (fn);
7240 if (bt == FFEINFO_basictypeNONE)
7242 ffeimplic_establish_symbol (fn);
7243 if (ffesymbol_funcresult (fn) != NULL)
7244 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
7245 bt = ffesymbol_basictype (fn);
7246 kt = ffesymbol_kindtype (fn);
7250 charfunc = cmplxfunc = FALSE;
7251 else if (bt == FFEINFO_basictypeCHARACTER)
7252 charfunc = TRUE, cmplxfunc = FALSE;
7253 else if ((bt == FFEINFO_basictypeCOMPLEX)
7254 && ffesymbol_is_f2c (fn)
7256 charfunc = FALSE, cmplxfunc = TRUE;
7258 charfunc = cmplxfunc = FALSE;
7260 if (multi || charfunc)
7261 type = ffecom_tree_fun_type_void;
7262 else if (ffesymbol_is_f2c (fn) && !altentries)
7263 type = ffecom_tree_fun_type[bt][kt];
7265 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
7267 if ((type == NULL_TREE)
7268 || (TREE_TYPE (type) == NULL_TREE))
7269 type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */
7272 case FFEINFO_kindSUBROUTINE:
7273 gt = FFEGLOBAL_typeSUBR;
7274 egt = FFEGLOBAL_typeEXT;
7275 bt = FFEINFO_basictypeNONE;
7276 kt = FFEINFO_kindtypeNONE;
7277 if (ffecom_is_altreturning_)
7278 type = ffecom_tree_subr_type;
7280 type = ffecom_tree_fun_type_void;
7286 assert ("say what??" == NULL);
7288 case FFEINFO_kindANY:
7289 gt = FFEGLOBAL_typeANY;
7290 bt = FFEINFO_basictypeNONE;
7291 kt = FFEINFO_kindtypeNONE;
7292 type = error_mark_node;
7300 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
7301 ffesymbol_text (fn));
7303 #if FFETARGET_isENFORCED_MAIN
7304 else if (main_program)
7305 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
7308 id = ffecom_get_external_identifier_ (fn);
7312 0, /* nested/inline */
7313 !altentries); /* TREE_PUBLIC */
7315 TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */
7318 && ((g = ffesymbol_global (fn)) != NULL)
7319 && ((ffeglobal_type (g) == gt)
7320 || (ffeglobal_type (g) == egt)))
7322 ffeglobal_set_hook (g, current_function_decl);
7325 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7326 exec-transitioning needs current_function_decl to be filled in. So we
7327 do these things in two phases. */
7330 { /* 1st arg identifies which entrypoint. */
7331 ffecom_which_entrypoint_decl_
7332 = build_decl (PARM_DECL,
7333 ffecom_get_invented_identifier ("__g77_%s",
7334 "which_entrypoint"),
7336 push_parm_decl (ffecom_which_entrypoint_decl_);
7342 { /* Arg for result (return value). */
7347 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
7349 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
7351 type = ffecom_multi_type_node_;
7353 result = ffecom_get_invented_identifier ("__g77_%s", "result");
7355 /* Make length arg _and_ enhance type info for CHAR arg itself. */
7358 length = ffecom_char_enhance_arg_ (&type, fn);
7360 length = NULL_TREE; /* Not ref'd if !charfunc. */
7362 type = build_pointer_type (type);
7363 result = build_decl (PARM_DECL, result, type);
7365 push_parm_decl (result);
7367 ffecom_multi_retval_ = result;
7369 ffecom_func_result_ = result;
7373 push_parm_decl (length);
7374 ffecom_func_length_ = length;
7378 if (ffecom_primary_entry_is_proc_)
7381 arglist = ffecom_master_arglist_;
7383 arglist = ffesymbol_dummyargs (fn);
7384 ffecom_push_dummy_decls_ (arglist, FALSE);
7387 if (TREE_CODE (current_function_decl) != ERROR_MARK)
7388 store_parm_decls (main_program ? 1 : 0);
7390 ffecom_start_compstmt ();
7391 /* Disallow temp vars at this level. */
7392 current_binding_level->prep_state = 2;
7394 lineno = old_lineno;
7395 input_filename = old_input_filename;
7397 /* This handles any symbols still untransformed, in case -g specified.
7398 This used to be done in ffecom_finish_progunit, but it turns out to
7399 be necessary to do it here so that statement functions are
7400 expanded before code. But don't bother for BLOCK DATA. */
7402 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
7403 ffesymbol_drive (ffecom_finish_symbol_transform_);
7407 /* ffecom_sym_transform_ -- Transform FFE sym into backend sym
7410 ffecom_sym_transform_(s);
7412 The ffesymbol_hook info for s is updated with appropriate backend info
7415 #if FFECOM_targetCURRENT == FFECOM_targetGCC
7417 ffecom_sym_transform_ (ffesymbol s)
7419 tree t; /* Transformed thingy. */
7420 tree tlen; /* Length if CHAR*(*). */
7421 bool addr; /* Is t the address of the thingy? */
7422 ffeinfoBasictype bt;
7425 int old_lineno = lineno;
7426 const char *old_input_filename = input_filename;
7428 /* Must ensure special ASSIGN variables are declared at top of outermost
7429 block, else they'll end up in the innermost block when their first
7430 ASSIGN is seen, which leaves them out of scope when they're the
7431 subject of a GOTO or I/O statement.
7433 We make this variable even if -fugly-assign. Just let it go unused,
7434 in case it turns out there are cases where we really want to use this
7435 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
7437 if (! ffecom_transform_only_dummies_
7438 && ffesymbol_assigned (s)
7439 && ! ffesymbol_hook (s).assign_tree)
7440 s = ffecom_sym_transform_assign_ (s);
7442 if (ffesymbol_sfdummyparent (s) == NULL)
7444 input_filename = ffesymbol_where_filename (s);
7445 lineno = ffesymbol_where_filelinenum (s);
7449 ffesymbol sf = ffesymbol_sfdummyparent (s);
7451 input_filename = ffesymbol_where_filename (sf);
7452 lineno = ffesymbol_where_filelinenum (sf);
7455 bt = ffeinfo_basictype (ffebld_info (s));
7456 kt = ffeinfo_kindtype (ffebld_info (s));
7462 switch (ffesymbol_kind (s))
7464 case FFEINFO_kindNONE:
7465 switch (ffesymbol_where (s))
7467 case FFEINFO_whereDUMMY: /* Subroutine or function. */
7468 assert (ffecom_transform_only_dummies_);
7470 /* Before 0.4, this could be ENTITY/DUMMY, but see
7471 ffestu_sym_end_transition -- no longer true (in particular, if
7472 it could be an ENTITY, it _will_ be made one, so that
7473 possibility won't come through here). So we never make length
7474 arg for CHARACTER type. */
7476 t = build_decl (PARM_DECL,
7477 ffecom_get_identifier_ (ffesymbol_text (s)),
7478 ffecom_tree_ptr_to_subr_type);
7480 DECL_ARTIFICIAL (t) = 1;
7485 case FFEINFO_whereGLOBAL: /* Subroutine or function. */
7486 assert (!ffecom_transform_only_dummies_);
7488 if (((g = ffesymbol_global (s)) != NULL)
7489 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7490 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7491 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
7492 && (ffeglobal_hook (g) != NULL_TREE)
7493 && ffe_is_globals ())
7495 t = ffeglobal_hook (g);
7499 t = build_decl (FUNCTION_DECL,
7500 ffecom_get_external_identifier_ (s),
7501 ffecom_tree_subr_type); /* Assume subr. */
7502 DECL_EXTERNAL (t) = 1;
7503 TREE_PUBLIC (t) = 1;
7505 t = start_decl (t, FALSE);
7506 finish_decl (t, NULL_TREE, FALSE);
7509 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
7510 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
7511 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
7512 ffeglobal_set_hook (g, t);
7514 ffecom_save_tree_forever (t);
7519 assert ("NONE where unexpected" == NULL);
7521 case FFEINFO_whereANY:
7526 case FFEINFO_kindENTITY:
7527 switch (ffeinfo_where (ffesymbol_info (s)))
7530 case FFEINFO_whereCONSTANT:
7531 /* ~~Debugging info needed? */
7532 assert (!ffecom_transform_only_dummies_);
7533 t = error_mark_node; /* Shouldn't ever see this in expr. */
7536 case FFEINFO_whereLOCAL:
7537 assert (!ffecom_transform_only_dummies_);
7540 ffestorag st = ffesymbol_storage (s);
7544 && (ffestorag_size (st) == 0))
7546 t = error_mark_node;
7550 type = ffecom_type_localvar_ (s, bt, kt);
7552 if (type == error_mark_node)
7554 t = error_mark_node;
7559 && (ffestorag_parent (st) != NULL))
7560 { /* Child of EQUIVALENCE parent. */
7563 ffetargetOffset offset;
7565 est = ffestorag_parent (st);
7566 ffecom_transform_equiv_ (est);
7568 et = ffestorag_hook (est);
7569 assert (et != NULL_TREE);
7571 if (! TREE_STATIC (et))
7572 put_var_into_stack (et);
7574 offset = ffestorag_modulo (est)
7575 + ffestorag_offset (ffesymbol_storage (s))
7576 - ffestorag_offset (est);
7578 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
7580 /* (t_type *) (((char *) &et) + offset) */
7582 t = convert (string_type_node, /* (char *) */
7583 ffecom_1 (ADDR_EXPR,
7584 build_pointer_type (TREE_TYPE (et)),
7586 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
7588 build_int_2 (offset, 0));
7589 t = convert (build_pointer_type (type),
7591 TREE_CONSTANT (t) = staticp (et);
7598 bool init = ffesymbol_is_init (s);
7600 t = build_decl (VAR_DECL,
7601 ffecom_get_identifier_ (ffesymbol_text (s)),
7605 || ffesymbol_namelisted (s)
7606 #ifdef FFECOM_sizeMAXSTACKITEM
7608 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
7610 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
7611 && (ffecom_primary_entry_kind_
7612 != FFEINFO_kindBLOCKDATA)
7613 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
7614 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
7616 TREE_STATIC (t) = 0; /* No need to make static. */
7618 if (init || ffe_is_init_local_zero ())
7619 DECL_INITIAL (t) = error_mark_node;
7621 /* Keep -Wunused from complaining about var if it
7622 is used as sfunc arg or DATA implied-DO. */
7623 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
7624 DECL_IN_SYSTEM_HEADER (t) = 1;
7626 t = start_decl (t, FALSE);
7630 if (ffesymbol_init (s) != NULL)
7631 initexpr = ffecom_expr (ffesymbol_init (s));
7633 initexpr = ffecom_init_zero_ (t);
7635 else if (ffe_is_init_local_zero ())
7636 initexpr = ffecom_init_zero_ (t);
7638 initexpr = NULL_TREE; /* Not ref'd if !init. */
7640 finish_decl (t, initexpr, FALSE);
7642 if (st != NULL && DECL_SIZE (t) != error_mark_node)
7644 assert (TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST);
7645 assert (0 == compare_tree_int (DECL_SIZE_UNIT (t),
7646 ffestorag_size (st)));
7652 case FFEINFO_whereRESULT:
7653 assert (!ffecom_transform_only_dummies_);
7655 if (bt == FFEINFO_basictypeCHARACTER)
7656 { /* Result is already in list of dummies, use
7658 t = ffecom_func_result_;
7659 tlen = ffecom_func_length_;
7663 if ((ffecom_num_entrypoints_ == 0)
7664 && (bt == FFEINFO_basictypeCOMPLEX)
7665 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
7666 { /* Result is already in list of dummies, use
7668 t = ffecom_func_result_;
7672 if (ffecom_func_result_ != NULL_TREE)
7674 t = ffecom_func_result_;
7677 if ((ffecom_num_entrypoints_ != 0)
7678 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
7680 assert (ffecom_multi_retval_ != NULL_TREE);
7681 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
7682 ffecom_multi_retval_);
7683 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
7684 t, ffecom_multi_fields_[bt][kt]);
7689 t = build_decl (VAR_DECL,
7690 ffecom_get_identifier_ (ffesymbol_text (s)),
7691 ffecom_tree_type[bt][kt]);
7692 TREE_STATIC (t) = 0; /* Put result on stack. */
7693 t = start_decl (t, FALSE);
7694 finish_decl (t, NULL_TREE, FALSE);
7696 ffecom_func_result_ = t;
7700 case FFEINFO_whereDUMMY:
7708 bool adjustable = FALSE; /* Conditionally adjustable? */
7710 type = ffecom_tree_type[bt][kt];
7711 if (ffesymbol_sfdummyparent (s) != NULL)
7713 if (current_function_decl == ffecom_outer_function_decl_)
7714 { /* Exec transition before sfunc
7715 context; get it later. */
7718 t = ffecom_get_identifier_ (ffesymbol_text
7719 (ffesymbol_sfdummyparent (s)));
7722 t = ffecom_get_identifier_ (ffesymbol_text (s));
7724 assert (ffecom_transform_only_dummies_);
7726 old_sizes = get_pending_sizes ();
7727 put_pending_sizes (old_sizes);
7729 if (bt == FFEINFO_basictypeCHARACTER)
7730 tlen = ffecom_char_enhance_arg_ (&type, s);
7731 type = ffecom_check_size_overflow_ (s, type, TRUE);
7733 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
7735 if (type == error_mark_node)
7738 dim = ffebld_head (dl);
7739 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
7740 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
7741 low = ffecom_integer_one_node;
7743 low = ffecom_expr (ffebld_left (dim));
7744 assert (ffebld_right (dim) != NULL);
7745 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
7746 || ffecom_doing_entry_)
7748 /* Used to just do high=low. But for ffecom_tree_
7749 canonize_ref_, it probably is important to correctly
7750 assess the size. E.g. given COMPLEX C(*),CFUNC and
7751 C(2)=CFUNC(C), overlap can happen, while it can't
7752 for, say, C(1)=CFUNC(C(2)). */
7753 /* Even more recently used to set to INT_MAX, but that
7754 broke when some overflow checking went into the back
7755 end. Now we just leave the upper bound unspecified. */
7759 high = ffecom_expr (ffebld_right (dim));
7761 /* Determine whether array is conditionally adjustable,
7762 to decide whether back-end magic is needed.
7764 Normally the front end uses the back-end function
7765 variable_size to wrap SAVE_EXPR's around expressions
7766 affecting the size/shape of an array so that the
7767 size/shape info doesn't change during execution
7768 of the compiled code even though variables and
7769 functions referenced in those expressions might.
7771 variable_size also makes sure those saved expressions
7772 get evaluated immediately upon entry to the
7773 compiled procedure -- the front end normally doesn't
7774 have to worry about that.
7776 However, there is a problem with this that affects
7777 g77's implementation of entry points, and that is
7778 that it is _not_ true that each invocation of the
7779 compiled procedure is permitted to evaluate
7780 array size/shape info -- because it is possible
7781 that, for some invocations, that info is invalid (in
7782 which case it is "promised" -- i.e. a violation of
7783 the Fortran standard -- that the compiled code
7784 won't reference the array or its size/shape
7785 during that particular invocation).
7787 To phrase this in C terms, consider this gcc function:
7789 void foo (int *n, float (*a)[*n])
7791 // a is "pointer to array ...", fyi.
7794 Suppose that, for some invocations, it is permitted
7795 for a caller of foo to do this:
7799 Now the _written_ code for foo can take such a call
7800 into account by either testing explicitly for whether
7801 (a == NULL) || (n == NULL) -- presumably it is
7802 not permitted to reference *a in various fashions
7803 if (n == NULL) I suppose -- or it can avoid it by
7804 looking at other info (other arguments, static/global
7807 However, this won't work in gcc 2.5.8 because it'll
7808 automatically emit the code to save the "*n"
7809 expression, which'll yield a NULL dereference for
7810 the "foo (NULL, NULL)" call, something the code
7811 for foo cannot prevent.
7813 g77 definitely needs to avoid executing such
7814 code anytime the pointer to the adjustable array
7815 is NULL, because even if its bounds expressions
7816 don't have any references to possible "absent"
7817 variables like "*n" -- say all variable references
7818 are to COMMON variables, i.e. global (though in C,
7819 local static could actually make sense) -- the
7820 expressions could yield other run-time problems
7821 for allowably "dead" values in those variables.
7823 For example, let's consider a more complicated
7829 void foo (float (*a)[i/j])
7834 The above is (essentially) quite valid for Fortran
7835 but, again, for a call like "foo (NULL);", it is
7836 permitted for i and j to be undefined when the
7837 call is made. If j happened to be zero, for
7838 example, emitting the code to evaluate "i/j"
7839 could result in a run-time error.
7841 Offhand, though I don't have my F77 or F90
7842 standards handy, it might even be valid for a
7843 bounds expression to contain a function reference,
7844 in which case I doubt it is permitted for an
7845 implementation to invoke that function in the
7846 Fortran case involved here (invocation of an
7847 alternate ENTRY point that doesn't have the adjustable
7848 array as one of its arguments).
7850 So, the code that the compiler would normally emit
7851 to preevaluate the size/shape info for an
7852 adjustable array _must not_ be executed at run time
7853 in certain cases. Specifically, for Fortran,
7854 the case is when the pointer to the adjustable
7855 array == NULL. (For gnu-ish C, it might be nice
7856 for the source code itself to specify an expression
7857 that, if TRUE, inhibits execution of the code. Or
7858 reverse the sense for elegance.)
7860 (Note that g77 could use a different test than NULL,
7861 actually, since it happens to always pass an
7862 integer to the called function that specifies which
7863 entry point is being invoked. Hmm, this might
7864 solve the next problem.)
7866 One way a user could, I suppose, write "foo" so
7867 it works is to insert COND_EXPR's for the
7868 size/shape info so the dangerous stuff isn't
7869 actually done, as in:
7871 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7876 The next problem is that the front end needs to
7877 be able to tell the back end about the array's
7878 decl _before_ it tells it about the conditional
7879 expression to inhibit evaluation of size/shape info,
7882 To solve this, the front end needs to be able
7883 to give the back end the expression to inhibit
7884 generation of the preevaluation code _after_
7885 it makes the decl for the adjustable array.
7887 Until then, the above example using the COND_EXPR
7888 doesn't pass muster with gcc because the "(a == NULL)"
7889 part has a reference to "a", which is still
7890 undefined at that point.
7892 g77 will therefore use a different mechanism in the
7896 && ((TREE_CODE (low) != INTEGER_CST)
7897 || (high && TREE_CODE (high) != INTEGER_CST)))
7900 #if 0 /* Old approach -- see below. */
7901 if (TREE_CODE (low) != INTEGER_CST)
7902 low = ffecom_3 (COND_EXPR, integer_type_node,
7903 ffecom_adjarray_passed_ (s),
7905 ffecom_integer_zero_node);
7907 if (high && TREE_CODE (high) != INTEGER_CST)
7908 high = ffecom_3 (COND_EXPR, integer_type_node,
7909 ffecom_adjarray_passed_ (s),
7911 ffecom_integer_zero_node);
7914 /* ~~~gcc/stor-layout.c (layout_type) should do this,
7915 probably. Fixes 950302-1.f. */
7917 if (TREE_CODE (low) != INTEGER_CST)
7918 low = variable_size (low);
7920 /* ~~~Similarly, this fixes dumb0.f. The C front end
7921 does this, which is why dumb0.c would work. */
7923 if (high && TREE_CODE (high) != INTEGER_CST)
7924 high = variable_size (high);
7929 build_range_type (ffecom_integer_type_node,
7931 type = ffecom_check_size_overflow_ (s, type, TRUE);
7934 if (type == error_mark_node)
7936 t = error_mark_node;
7940 if ((ffesymbol_sfdummyparent (s) == NULL)
7941 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
7943 type = build_pointer_type (type);
7947 t = build_decl (PARM_DECL, t, type);
7949 DECL_ARTIFICIAL (t) = 1;
7952 /* If this arg is present in every entry point's list of
7953 dummy args, then we're done. */
7955 if (ffesymbol_numentries (s)
7956 == (ffecom_num_entrypoints_ + 1))
7961 /* If variable_size in stor-layout has been called during
7962 the above, then get_pending_sizes should have the
7963 yet-to-be-evaluated saved expressions pending.
7964 Make the whole lot of them get emitted, conditionally
7965 on whether the array decl ("t" above) is not NULL. */
7968 tree sizes = get_pending_sizes ();
7973 tem = TREE_CHAIN (tem))
7975 tree temv = TREE_VALUE (tem);
7981 = ffecom_2 (COMPOUND_EXPR,
7990 = ffecom_3 (COND_EXPR,
7997 convert (TREE_TYPE (sizes),
7998 integer_zero_node));
7999 sizes = ffecom_save_tree (sizes);
8002 = tree_cons (NULL_TREE, sizes, tem);
8006 put_pending_sizes (sizes);
8012 && (ffesymbol_numentries (s)
8013 != ffecom_num_entrypoints_ + 1))
8015 = ffecom_2 (NE_EXPR, integer_type_node,
8021 && (ffesymbol_numentries (s)
8022 != ffecom_num_entrypoints_ + 1))
8024 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
8025 ffebad_here (0, ffesymbol_where_line (s),
8026 ffesymbol_where_column (s));
8027 ffebad_string (ffesymbol_text (s));
8036 case FFEINFO_whereCOMMON:
8041 ffestorag st = ffesymbol_storage (s);
8044 cs = ffesymbol_common (s); /* The COMMON area itself. */
8045 if (st != NULL) /* Else not laid out. */
8047 ffecom_transform_common_ (cs);
8048 st = ffesymbol_storage (s);
8051 type = ffecom_type_localvar_ (s, bt, kt);
8053 cg = ffesymbol_global (cs); /* The global COMMON info. */
8055 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
8058 ct = ffeglobal_hook (cg); /* The common area's tree. */
8060 if ((ct == NULL_TREE)
8062 || (type == error_mark_node))
8063 t = error_mark_node;
8066 ffetargetOffset offset;
8069 cst = ffestorag_parent (st);
8070 assert (cst == ffesymbol_storage (cs));
8072 offset = ffestorag_modulo (cst)
8073 + ffestorag_offset (st)
8074 - ffestorag_offset (cst);
8076 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
8078 /* (t_type *) (((char *) &ct) + offset) */
8080 t = convert (string_type_node, /* (char *) */
8081 ffecom_1 (ADDR_EXPR,
8082 build_pointer_type (TREE_TYPE (ct)),
8084 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
8086 build_int_2 (offset, 0));
8087 t = convert (build_pointer_type (type),
8089 TREE_CONSTANT (t) = 1;
8096 case FFEINFO_whereIMMEDIATE:
8097 case FFEINFO_whereGLOBAL:
8098 case FFEINFO_whereFLEETING:
8099 case FFEINFO_whereFLEETING_CADDR:
8100 case FFEINFO_whereFLEETING_IADDR:
8101 case FFEINFO_whereINTRINSIC:
8102 case FFEINFO_whereCONSTANT_SUBOBJECT:
8104 assert ("ENTITY where unheard of" == NULL);
8106 case FFEINFO_whereANY:
8107 t = error_mark_node;
8112 case FFEINFO_kindFUNCTION:
8113 switch (ffeinfo_where (ffesymbol_info (s)))
8115 case FFEINFO_whereLOCAL: /* Me. */
8116 assert (!ffecom_transform_only_dummies_);
8117 t = current_function_decl;
8120 case FFEINFO_whereGLOBAL:
8121 assert (!ffecom_transform_only_dummies_);
8123 if (((g = ffesymbol_global (s)) != NULL)
8124 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8125 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8126 && (ffeglobal_hook (g) != NULL_TREE)
8127 && ffe_is_globals ())
8129 t = ffeglobal_hook (g);
8133 if (ffesymbol_is_f2c (s)
8134 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8135 t = ffecom_tree_fun_type[bt][kt];
8137 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
8139 t = build_decl (FUNCTION_DECL,
8140 ffecom_get_external_identifier_ (s),
8142 DECL_EXTERNAL (t) = 1;
8143 TREE_PUBLIC (t) = 1;
8145 t = start_decl (t, FALSE);
8146 finish_decl (t, NULL_TREE, FALSE);
8149 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
8150 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8151 ffeglobal_set_hook (g, t);
8153 ffecom_save_tree_forever (t);
8157 case FFEINFO_whereDUMMY:
8158 assert (ffecom_transform_only_dummies_);
8160 if (ffesymbol_is_f2c (s)
8161 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
8162 t = ffecom_tree_ptr_to_fun_type[bt][kt];
8164 t = build_pointer_type
8165 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
8167 t = build_decl (PARM_DECL,
8168 ffecom_get_identifier_ (ffesymbol_text (s)),
8171 DECL_ARTIFICIAL (t) = 1;
8176 case FFEINFO_whereCONSTANT: /* Statement function. */
8177 assert (!ffecom_transform_only_dummies_);
8178 t = ffecom_gen_sfuncdef_ (s, bt, kt);
8181 case FFEINFO_whereINTRINSIC:
8182 assert (!ffecom_transform_only_dummies_);
8183 break; /* Let actual references generate their
8187 assert ("FUNCTION where unheard of" == NULL);
8189 case FFEINFO_whereANY:
8190 t = error_mark_node;
8195 case FFEINFO_kindSUBROUTINE:
8196 switch (ffeinfo_where (ffesymbol_info (s)))
8198 case FFEINFO_whereLOCAL: /* Me. */
8199 assert (!ffecom_transform_only_dummies_);
8200 t = current_function_decl;
8203 case FFEINFO_whereGLOBAL:
8204 assert (!ffecom_transform_only_dummies_);
8206 if (((g = ffesymbol_global (s)) != NULL)
8207 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8208 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
8209 && (ffeglobal_hook (g) != NULL_TREE)
8210 && ffe_is_globals ())
8212 t = ffeglobal_hook (g);
8216 t = build_decl (FUNCTION_DECL,
8217 ffecom_get_external_identifier_ (s),
8218 ffecom_tree_subr_type);
8219 DECL_EXTERNAL (t) = 1;
8220 TREE_PUBLIC (t) = 1;
8222 t = start_decl (t, FALSE);
8223 finish_decl (t, NULL_TREE, FALSE);
8226 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
8227 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
8228 ffeglobal_set_hook (g, t);
8230 ffecom_save_tree_forever (t);
8234 case FFEINFO_whereDUMMY:
8235 assert (ffecom_transform_only_dummies_);
8237 t = build_decl (PARM_DECL,
8238 ffecom_get_identifier_ (ffesymbol_text (s)),
8239 ffecom_tree_ptr_to_subr_type);
8241 DECL_ARTIFICIAL (t) = 1;
8246 case FFEINFO_whereINTRINSIC:
8247 assert (!ffecom_transform_only_dummies_);
8248 break; /* Let actual references generate their
8252 assert ("SUBROUTINE where unheard of" == NULL);
8254 case FFEINFO_whereANY:
8255 t = error_mark_node;
8260 case FFEINFO_kindPROGRAM:
8261 switch (ffeinfo_where (ffesymbol_info (s)))
8263 case FFEINFO_whereLOCAL: /* Me. */
8264 assert (!ffecom_transform_only_dummies_);
8265 t = current_function_decl;
8268 case FFEINFO_whereCOMMON:
8269 case FFEINFO_whereDUMMY:
8270 case FFEINFO_whereGLOBAL:
8271 case FFEINFO_whereRESULT:
8272 case FFEINFO_whereFLEETING:
8273 case FFEINFO_whereFLEETING_CADDR:
8274 case FFEINFO_whereFLEETING_IADDR:
8275 case FFEINFO_whereIMMEDIATE:
8276 case FFEINFO_whereINTRINSIC:
8277 case FFEINFO_whereCONSTANT:
8278 case FFEINFO_whereCONSTANT_SUBOBJECT:
8280 assert ("PROGRAM where unheard of" == NULL);
8282 case FFEINFO_whereANY:
8283 t = error_mark_node;
8288 case FFEINFO_kindBLOCKDATA:
8289 switch (ffeinfo_where (ffesymbol_info (s)))
8291 case FFEINFO_whereLOCAL: /* Me. */
8292 assert (!ffecom_transform_only_dummies_);
8293 t = current_function_decl;
8296 case FFEINFO_whereGLOBAL:
8297 assert (!ffecom_transform_only_dummies_);
8299 t = build_decl (FUNCTION_DECL,
8300 ffecom_get_external_identifier_ (s),
8301 ffecom_tree_blockdata_type);
8302 DECL_EXTERNAL (t) = 1;
8303 TREE_PUBLIC (t) = 1;
8305 t = start_decl (t, FALSE);
8306 finish_decl (t, NULL_TREE, FALSE);
8308 ffecom_save_tree_forever (t);
8312 case FFEINFO_whereCOMMON:
8313 case FFEINFO_whereDUMMY:
8314 case FFEINFO_whereRESULT:
8315 case FFEINFO_whereFLEETING:
8316 case FFEINFO_whereFLEETING_CADDR:
8317 case FFEINFO_whereFLEETING_IADDR:
8318 case FFEINFO_whereIMMEDIATE:
8319 case FFEINFO_whereINTRINSIC:
8320 case FFEINFO_whereCONSTANT:
8321 case FFEINFO_whereCONSTANT_SUBOBJECT:
8323 assert ("BLOCKDATA where unheard of" == NULL);
8325 case FFEINFO_whereANY:
8326 t = error_mark_node;
8331 case FFEINFO_kindCOMMON:
8332 switch (ffeinfo_where (ffesymbol_info (s)))
8334 case FFEINFO_whereLOCAL:
8335 assert (!ffecom_transform_only_dummies_);
8336 ffecom_transform_common_ (s);
8339 case FFEINFO_whereNONE:
8340 case FFEINFO_whereCOMMON:
8341 case FFEINFO_whereDUMMY:
8342 case FFEINFO_whereGLOBAL:
8343 case FFEINFO_whereRESULT:
8344 case FFEINFO_whereFLEETING:
8345 case FFEINFO_whereFLEETING_CADDR:
8346 case FFEINFO_whereFLEETING_IADDR:
8347 case FFEINFO_whereIMMEDIATE:
8348 case FFEINFO_whereINTRINSIC:
8349 case FFEINFO_whereCONSTANT:
8350 case FFEINFO_whereCONSTANT_SUBOBJECT:
8352 assert ("COMMON where unheard of" == NULL);
8354 case FFEINFO_whereANY:
8355 t = error_mark_node;
8360 case FFEINFO_kindCONSTRUCT:
8361 switch (ffeinfo_where (ffesymbol_info (s)))
8363 case FFEINFO_whereLOCAL:
8364 assert (!ffecom_transform_only_dummies_);
8367 case FFEINFO_whereNONE:
8368 case FFEINFO_whereCOMMON:
8369 case FFEINFO_whereDUMMY:
8370 case FFEINFO_whereGLOBAL:
8371 case FFEINFO_whereRESULT:
8372 case FFEINFO_whereFLEETING:
8373 case FFEINFO_whereFLEETING_CADDR:
8374 case FFEINFO_whereFLEETING_IADDR:
8375 case FFEINFO_whereIMMEDIATE:
8376 case FFEINFO_whereINTRINSIC:
8377 case FFEINFO_whereCONSTANT:
8378 case FFEINFO_whereCONSTANT_SUBOBJECT:
8380 assert ("CONSTRUCT where unheard of" == NULL);
8382 case FFEINFO_whereANY:
8383 t = error_mark_node;
8388 case FFEINFO_kindNAMELIST:
8389 switch (ffeinfo_where (ffesymbol_info (s)))
8391 case FFEINFO_whereLOCAL:
8392 assert (!ffecom_transform_only_dummies_);
8393 t = ffecom_transform_namelist_ (s);
8396 case FFEINFO_whereNONE:
8397 case FFEINFO_whereCOMMON:
8398 case FFEINFO_whereDUMMY:
8399 case FFEINFO_whereGLOBAL:
8400 case FFEINFO_whereRESULT:
8401 case FFEINFO_whereFLEETING:
8402 case FFEINFO_whereFLEETING_CADDR:
8403 case FFEINFO_whereFLEETING_IADDR:
8404 case FFEINFO_whereIMMEDIATE:
8405 case FFEINFO_whereINTRINSIC:
8406 case FFEINFO_whereCONSTANT:
8407 case FFEINFO_whereCONSTANT_SUBOBJECT:
8409 assert ("NAMELIST where unheard of" == NULL);
8411 case FFEINFO_whereANY:
8412 t = error_mark_node;
8418 assert ("kind unheard of" == NULL);
8420 case FFEINFO_kindANY:
8421 t = error_mark_node;
8425 ffesymbol_hook (s).decl_tree = t;
8426 ffesymbol_hook (s).length_tree = tlen;
8427 ffesymbol_hook (s).addr = addr;
8429 lineno = old_lineno;
8430 input_filename = old_input_filename;
8436 /* Transform into ASSIGNable symbol.
8438 Symbol has already been transformed, but for whatever reason, the
8439 resulting decl_tree has been deemed not usable for an ASSIGN target.
8440 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8441 another local symbol of type void * and stuff that in the assign_tree
8442 argument. The F77/F90 standards allow this implementation. */
8444 #if FFECOM_targetCURRENT == FFECOM_targetGCC
8446 ffecom_sym_transform_assign_ (ffesymbol s)
8448 tree t; /* Transformed thingy. */
8449 int old_lineno = lineno;
8450 const char *old_input_filename = input_filename;
8452 if (ffesymbol_sfdummyparent (s) == NULL)
8454 input_filename = ffesymbol_where_filename (s);
8455 lineno = ffesymbol_where_filelinenum (s);
8459 ffesymbol sf = ffesymbol_sfdummyparent (s);
8461 input_filename = ffesymbol_where_filename (sf);
8462 lineno = ffesymbol_where_filelinenum (sf);
8465 assert (!ffecom_transform_only_dummies_);
8467 t = build_decl (VAR_DECL,
8468 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
8469 ffesymbol_text (s)),
8470 TREE_TYPE (null_pointer_node));
8472 switch (ffesymbol_where (s))
8474 case FFEINFO_whereLOCAL:
8475 /* Unlike for regular vars, SAVE status is easy to determine for
8476 ASSIGNed vars, since there's no initialization, there's no
8477 effective storage association (so "SAVE J" does not apply to
8478 K even given "EQUIVALENCE (J,K)"), there's no size issue
8479 to worry about, etc. */
8480 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
8481 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8482 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
8483 TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */
8485 TREE_STATIC (t) = 0; /* No need to make static. */
8488 case FFEINFO_whereCOMMON:
8489 TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */
8492 case FFEINFO_whereDUMMY:
8493 /* Note that twinning a DUMMY means the caller won't see
8494 the ASSIGNed value. But both F77 and F90 allow implementations
8495 to do this, i.e. disallow Fortran code that would try and
8496 take advantage of actually putting a label into a variable
8497 via a dummy argument (or any other storage association, for
8499 TREE_STATIC (t) = 0;
8503 TREE_STATIC (t) = 0;
8507 t = start_decl (t, FALSE);
8508 finish_decl (t, NULL_TREE, FALSE);
8510 ffesymbol_hook (s).assign_tree = t;
8512 lineno = old_lineno;
8513 input_filename = old_input_filename;
8519 /* Implement COMMON area in back end.
8521 Because COMMON-based variables can be referenced in the dimension
8522 expressions of dummy (adjustable) arrays, and because dummies
8523 (in the gcc back end) need to be put in the outer binding level
8524 of a function (which has two binding levels, the outer holding
8525 the dummies and the inner holding the other vars), special care
8526 must be taken to handle COMMON areas.
8528 The current strategy is basically to always tell the back end about
8529 the COMMON area as a top-level external reference to just a block
8530 of storage of the master type of that area (e.g. integer, real,
8531 character, whatever -- not a structure). As a distinct action,
8532 if initial values are provided, tell the back end about the area
8533 as a top-level non-external (initialized) area and remember not to
8534 allow further initialization or expansion of the area. Meanwhile,
8535 if no initialization happens at all, tell the back end about
8536 the largest size we've seen declared so the space does get reserved.
8537 (This function doesn't handle all that stuff, but it does some
8538 of the important things.)
8540 Meanwhile, for COMMON variables themselves, just keep creating
8541 references like *((float *) (&common_area + offset)) each time
8542 we reference the variable. In other words, don't make a VAR_DECL
8543 or any kind of component reference (like we used to do before 0.4),
8544 though we might do that as well just for debugging purposes (and
8545 stuff the rtl with the appropriate offset expression). */
8547 #if FFECOM_targetCURRENT == FFECOM_targetGCC
8549 ffecom_transform_common_ (ffesymbol s)
8551 ffestorag st = ffesymbol_storage (s);
8552 ffeglobal g = ffesymbol_global (s);
8557 bool is_init = ffestorag_is_init (st);
8559 assert (st != NULL);
8562 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
8565 /* First update the size of the area in global terms. */
8567 ffeglobal_size_common (s, ffestorag_size (st));
8569 if (!ffeglobal_common_init (g))
8570 is_init = FALSE; /* No explicit init, don't let erroneous joins init. */
8572 cbt = ffeglobal_hook (g);
8574 /* If we already have declared this common block for a previous program
8575 unit, and either we already initialized it or we don't have new
8576 initialization for it, just return what we have without changing it. */
8578 if ((cbt != NULL_TREE)
8580 || !DECL_EXTERNAL (cbt)))
8582 if (st->hook == NULL) ffestorag_set_hook (st, cbt);
8586 /* Process inits. */
8590 if (ffestorag_init (st) != NULL)
8594 /* Set the padding for the expression, so ffecom_expr
8595 knows to insert that many zeros. */
8596 switch (ffebld_op (sexp = ffestorag_init (st)))
8598 case FFEBLD_opCONTER:
8599 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
8602 case FFEBLD_opARRTER:
8603 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
8606 case FFEBLD_opACCTER:
8607 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
8611 assert ("bad op for cmn init (pad)" == NULL);
8615 init = ffecom_expr (sexp);
8616 if (init == error_mark_node)
8617 { /* Hopefully the back end complained! */
8619 if (cbt != NULL_TREE)
8624 init = error_mark_node;
8629 /* cbtype must be permanently allocated! */
8631 /* Allocate the MAX of the areas so far, seen filewide. */
8632 high = build_int_2 ((ffeglobal_common_size (g)
8633 + ffeglobal_common_pad (g)) - 1, 0);
8634 TREE_TYPE (high) = ffecom_integer_type_node;
8637 cbtype = build_array_type (char_type_node,
8638 build_range_type (integer_type_node,
8642 cbtype = build_array_type (char_type_node, NULL_TREE);
8644 if (cbt == NULL_TREE)
8647 = build_decl (VAR_DECL,
8648 ffecom_get_external_identifier_ (s),
8650 TREE_STATIC (cbt) = 1;
8651 TREE_PUBLIC (cbt) = 1;
8656 TREE_TYPE (cbt) = cbtype;
8658 DECL_EXTERNAL (cbt) = init ? 0 : 1;
8659 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
8661 cbt = start_decl (cbt, TRUE);
8662 if (ffeglobal_hook (g) != NULL)
8663 assert (cbt == ffeglobal_hook (g));
8665 assert (!init || !DECL_EXTERNAL (cbt));
8667 /* Make sure that any type can live in COMMON and be referenced
8668 without getting a bus error. We could pick the most restrictive
8669 alignment of all entities actually placed in the COMMON, but
8670 this seems easy enough. */
8672 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
8673 DECL_USER_ALIGN (cbt) = 0;
8675 if (is_init && (ffestorag_init (st) == NULL))
8676 init = ffecom_init_zero_ (cbt);
8678 finish_decl (cbt, init, TRUE);
8681 ffestorag_set_init (st, ffebld_new_any ());
8685 assert (DECL_SIZE_UNIT (cbt) != NULL_TREE);
8686 assert (TREE_CODE (DECL_SIZE_UNIT (cbt)) == INTEGER_CST);
8687 assert (0 == compare_tree_int (DECL_SIZE_UNIT (cbt),
8688 (ffeglobal_common_size (g)
8689 + ffeglobal_common_pad (g))));
8692 ffeglobal_set_hook (g, cbt);
8694 ffestorag_set_hook (st, cbt);
8696 ffecom_save_tree_forever (cbt);
8700 /* Make master area for local EQUIVALENCE. */
8702 #if FFECOM_targetCURRENT == FFECOM_targetGCC
8704 ffecom_transform_equiv_ (ffestorag eqst)
8710 bool is_init = ffestorag_is_init (eqst);
8712 assert (eqst != NULL);
8714 eqt = ffestorag_hook (eqst);
8716 if (eqt != NULL_TREE)
8719 /* Process inits. */
8723 if (ffestorag_init (eqst) != NULL)
8727 /* Set the padding for the expression, so ffecom_expr
8728 knows to insert that many zeros. */
8729 switch (ffebld_op (sexp = ffestorag_init (eqst)))
8731 case FFEBLD_opCONTER:
8732 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
8735 case FFEBLD_opARRTER:
8736 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
8739 case FFEBLD_opACCTER:
8740 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
8744 assert ("bad op for eqv init (pad)" == NULL);
8748 init = ffecom_expr (sexp);
8749 if (init == error_mark_node)
8750 init = NULL_TREE; /* Hopefully the back end complained! */
8753 init = error_mark_node;
8755 else if (ffe_is_init_local_zero ())
8756 init = error_mark_node;
8760 ffecom_member_namelisted_ = FALSE;
8761 ffestorag_drive (ffestorag_list_equivs (eqst),
8762 &ffecom_member_phase1_,
8765 high = build_int_2 ((ffestorag_size (eqst)
8766 + ffestorag_modulo (eqst)) - 1, 0);
8767 TREE_TYPE (high) = ffecom_integer_type_node;
8769 eqtype = build_array_type (char_type_node,
8770 build_range_type (ffecom_integer_type_node,
8771 ffecom_integer_zero_node,
8774 eqt = build_decl (VAR_DECL,
8775 ffecom_get_invented_identifier ("__g77_equiv_%s",
8777 (ffestorag_symbol (eqst))),
8779 DECL_EXTERNAL (eqt) = 0;
8781 || ffecom_member_namelisted_
8782 #ifdef FFECOM_sizeMAXSTACKITEM
8783 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
8785 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
8786 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
8787 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
8788 TREE_STATIC (eqt) = 1;
8790 TREE_STATIC (eqt) = 0;
8791 TREE_PUBLIC (eqt) = 0;
8792 TREE_ADDRESSABLE (eqt) = 1; /* Ensure non-register allocation */
8793 DECL_CONTEXT (eqt) = current_function_decl;
8795 DECL_INITIAL (eqt) = error_mark_node;
8797 DECL_INITIAL (eqt) = NULL_TREE;
8799 eqt = start_decl (eqt, FALSE);
8801 /* Make sure that any type can live in EQUIVALENCE and be referenced
8802 without getting a bus error. We could pick the most restrictive
8803 alignment of all entities actually placed in the EQUIVALENCE, but
8804 this seems easy enough. */
8806 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
8807 DECL_USER_ALIGN (eqt) = 0;
8809 if ((!is_init && ffe_is_init_local_zero ())
8810 || (is_init && (ffestorag_init (eqst) == NULL)))
8811 init = ffecom_init_zero_ (eqt);
8813 finish_decl (eqt, init, FALSE);
8816 ffestorag_set_init (eqst, ffebld_new_any ());
8819 assert (TREE_CODE (DECL_SIZE_UNIT (eqt)) == INTEGER_CST);
8820 assert (0 == compare_tree_int (DECL_SIZE_UNIT (eqt),
8821 (ffestorag_size (eqst)
8822 + ffestorag_modulo (eqst))));
8825 ffestorag_set_hook (eqst, eqt);
8827 ffestorag_drive (ffestorag_list_equivs (eqst),
8828 &ffecom_member_phase2_,
8833 /* Implement NAMELIST in back end. See f2c/format.c for more info. */
8835 #if FFECOM_targetCURRENT == FFECOM_targetGCC
8837 ffecom_transform_namelist_ (ffesymbol s)
8840 tree nmltype = ffecom_type_namelist_ ();
8848 static int mynumber = 0;
8850 nmlt = build_decl (VAR_DECL,
8851 ffecom_get_invented_identifier ("__g77_namelist_%d",
8854 TREE_STATIC (nmlt) = 1;
8855 DECL_INITIAL (nmlt) = error_mark_node;
8857 nmlt = start_decl (nmlt, FALSE);
8859 /* Process inits. */
8861 i = strlen (ffesymbol_text (s));
8863 high = build_int_2 (i, 0);
8864 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
8866 nameinit = ffecom_build_f2c_string_ (i + 1,
8867 ffesymbol_text (s));
8868 TREE_TYPE (nameinit)
8869 = build_type_variant
8872 build_range_type (ffecom_f2c_ftnlen_type_node,
8873 ffecom_f2c_ftnlen_one_node,
8876 TREE_CONSTANT (nameinit) = 1;
8877 TREE_STATIC (nameinit) = 1;
8878 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
8881 varsinit = ffecom_vardesc_array_ (s);
8882 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
8884 TREE_CONSTANT (varsinit) = 1;
8885 TREE_STATIC (varsinit) = 1;
8890 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
8893 nvarsinit = build_int_2 (i, 0);
8894 TREE_TYPE (nvarsinit) = integer_type_node;
8895 TREE_CONSTANT (nvarsinit) = 1;
8896 TREE_STATIC (nvarsinit) = 1;
8898 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
8899 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
8901 TREE_CHAIN (TREE_CHAIN (nmlinits))
8902 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
8904 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
8905 TREE_CONSTANT (nmlinits) = 1;
8906 TREE_STATIC (nmlinits) = 1;
8908 finish_decl (nmlt, nmlinits, FALSE);
8910 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
8917 /* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
8918 analyzed on the assumption it is calculating a pointer to be
8919 indirected through. It must return the proper decl and offset,
8920 taking into account different units of measurements for offsets. */
8922 #if FFECOM_targetCURRENT == FFECOM_targetGCC
8924 ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
8927 switch (TREE_CODE (t))
8931 case NON_LVALUE_EXPR:
8932 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
8936 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
8937 if ((*decl == NULL_TREE)
8938 || (*decl == error_mark_node))
8941 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
8943 /* An offset into COMMON. */
8944 *offset = fold (build (PLUS_EXPR, TREE_TYPE (*offset),
8945 *offset, TREE_OPERAND (t, 1)));
8946 /* Convert offset (presumably in bytes) into canonical units
8947 (presumably bits). */
8948 *offset = size_binop (MULT_EXPR,
8949 convert (bitsizetype, *offset),
8950 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))));
8953 /* Not a COMMON reference, so an unrecognized pattern. */
8954 *decl = error_mark_node;
8959 *offset = bitsize_zero_node;
8963 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
8965 /* A reference to COMMON. */
8966 *decl = TREE_OPERAND (t, 0);
8967 *offset = bitsize_zero_node;
8972 /* Not a COMMON reference, so an unrecognized pattern. */
8973 *decl = error_mark_node;
8979 /* Given a tree that is possibly intended for use as an lvalue, return
8980 information representing a canonical view of that tree as a decl, an
8981 offset into that decl, and a size for the lvalue.
8983 If there's no applicable decl, NULL_TREE is returned for the decl,
8984 and the other fields are left undefined.
8986 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
8987 is returned for the decl, and the other fields are left undefined.
8989 Otherwise, the decl returned currently is either a VAR_DECL or a
8992 The offset returned is always valid, but of course not necessarily
8993 a constant, and not necessarily converted into the appropriate
8994 type, leaving that up to the caller (so as to avoid that overhead
8995 if the decls being looked at are different anyway).
8997 If the size cannot be determined (e.g. an adjustable array),
8998 an ERROR_MARK node is returned for the size. Otherwise, the
8999 size returned is valid, not necessarily a constant, and not
9000 necessarily converted into the appropriate type as with the
9003 Note that the offset and size expressions are expressed in the
9004 base storage units (usually bits) rather than in the units of
9005 the type of the decl, because two decls with different types
9006 might overlap but with apparently non-overlapping array offsets,
9007 whereas converting the array offsets to consistant offsets will
9008 reveal the overlap. */
9010 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9012 ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
9015 /* The default path is to report a nonexistant decl. */
9021 switch (TREE_CODE (t))
9024 case IDENTIFIER_NODE:
9033 case TRUNC_DIV_EXPR:
9035 case FLOOR_DIV_EXPR:
9036 case ROUND_DIV_EXPR:
9037 case TRUNC_MOD_EXPR:
9039 case FLOOR_MOD_EXPR:
9040 case ROUND_MOD_EXPR:
9042 case EXACT_DIV_EXPR:
9043 case FIX_TRUNC_EXPR:
9045 case FIX_FLOOR_EXPR:
9046 case FIX_ROUND_EXPR:
9060 case BIT_ANDTC_EXPR:
9062 case TRUTH_ANDIF_EXPR:
9063 case TRUTH_ORIF_EXPR:
9064 case TRUTH_AND_EXPR:
9066 case TRUTH_XOR_EXPR:
9067 case TRUTH_NOT_EXPR:
9087 *offset = bitsize_zero_node;
9088 *size = TYPE_SIZE (TREE_TYPE (t));
9093 tree array = TREE_OPERAND (t, 0);
9094 tree element = TREE_OPERAND (t, 1);
9097 if ((array == NULL_TREE)
9098 || (element == NULL_TREE))
9100 *decl = error_mark_node;
9104 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
9106 if ((*decl == NULL_TREE)
9107 || (*decl == error_mark_node))
9110 /* Calculate ((element - base) * NBBY) + init_offset. */
9111 *offset = fold (build (MINUS_EXPR, TREE_TYPE (element),
9113 TYPE_MIN_VALUE (TYPE_DOMAIN
9114 (TREE_TYPE (array)))));
9116 *offset = size_binop (MULT_EXPR,
9117 convert (bitsizetype, *offset),
9118 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))));
9120 *offset = size_binop (PLUS_EXPR, init_offset, *offset);
9122 *size = TYPE_SIZE (TREE_TYPE (t));
9128 /* Most of this code is to handle references to COMMON. And so
9129 far that is useful only for calling library functions, since
9130 external (user) functions might reference common areas. But
9131 even calling an external function, it's worthwhile to decode
9132 COMMON references because if not storing into COMMON, we don't
9133 want COMMON-based arguments to gratuitously force use of a
9136 *size = TYPE_SIZE (TREE_TYPE (t));
9138 ffecom_tree_canonize_ptr_ (decl, offset,
9139 TREE_OPERAND (t, 0));
9146 case NON_LVALUE_EXPR:
9149 case COND_EXPR: /* More cases than we can handle. */
9151 case REFERENCE_EXPR:
9152 case PREDECREMENT_EXPR:
9153 case PREINCREMENT_EXPR:
9154 case POSTDECREMENT_EXPR:
9155 case POSTINCREMENT_EXPR:
9158 *decl = error_mark_node;
9164 /* Do divide operation appropriate to type of operands. */
9166 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9168 ffecom_tree_divide_ (tree tree_type, tree left, tree right,
9169 tree dest_tree, ffebld dest, bool *dest_used,
9172 if ((left == error_mark_node)
9173 || (right == error_mark_node))
9174 return error_mark_node;
9176 switch (TREE_CODE (tree_type))
9179 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
9184 if (! optimize_size)
9185 return ffecom_2 (RDIV_EXPR, tree_type,
9191 if (TREE_TYPE (tree_type)
9192 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9193 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9195 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9197 left = ffecom_1 (ADDR_EXPR,
9198 build_pointer_type (TREE_TYPE (left)),
9200 left = build_tree_list (NULL_TREE, left);
9201 right = ffecom_1 (ADDR_EXPR,
9202 build_pointer_type (TREE_TYPE (right)),
9204 right = build_tree_list (NULL_TREE, right);
9205 TREE_CHAIN (left) = right;
9207 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9208 ffecom_gfrt_kindtype (ix),
9209 ffe_is_f2c_library (),
9212 dest_tree, dest, dest_used,
9213 NULL_TREE, TRUE, hook);
9221 if (TREE_TYPE (TYPE_FIELDS (tree_type))
9222 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
9223 ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */
9225 ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */
9227 left = ffecom_1 (ADDR_EXPR,
9228 build_pointer_type (TREE_TYPE (left)),
9230 left = build_tree_list (NULL_TREE, left);
9231 right = ffecom_1 (ADDR_EXPR,
9232 build_pointer_type (TREE_TYPE (right)),
9234 right = build_tree_list (NULL_TREE, right);
9235 TREE_CHAIN (left) = right;
9237 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
9238 ffecom_gfrt_kindtype (ix),
9239 ffe_is_f2c_library (),
9242 dest_tree, dest, dest_used,
9243 NULL_TREE, TRUE, hook);
9248 return ffecom_2 (RDIV_EXPR, tree_type,
9255 /* Build type info for non-dummy variable. */
9257 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9259 ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
9268 type = ffecom_tree_type[bt][kt];
9269 if (bt == FFEINFO_basictypeCHARACTER)
9271 hight = build_int_2 (ffesymbol_size (s), 0);
9272 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
9277 build_range_type (ffecom_f2c_ftnlen_type_node,
9278 ffecom_f2c_ftnlen_one_node,
9280 type = ffecom_check_size_overflow_ (s, type, FALSE);
9283 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
9285 if (type == error_mark_node)
9288 dim = ffebld_head (dl);
9289 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
9291 if (ffebld_left (dim) == NULL)
9292 lowt = integer_one_node;
9294 lowt = ffecom_expr (ffebld_left (dim));
9296 if (TREE_CODE (lowt) != INTEGER_CST)
9297 lowt = variable_size (lowt);
9299 assert (ffebld_right (dim) != NULL);
9300 hight = ffecom_expr (ffebld_right (dim));
9302 if (TREE_CODE (hight) != INTEGER_CST)
9303 hight = variable_size (hight);
9305 type = build_array_type (type,
9306 build_range_type (ffecom_integer_type_node,
9308 type = ffecom_check_size_overflow_ (s, type, FALSE);
9315 /* Build Namelist type. */
9317 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9319 ffecom_type_namelist_ ()
9321 static tree type = NULL_TREE;
9323 if (type == NULL_TREE)
9325 static tree namefield, varsfield, nvarsfield;
9328 vardesctype = ffecom_type_vardesc_ ();
9330 type = make_node (RECORD_TYPE);
9332 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
9334 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9336 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
9337 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
9340 TYPE_FIELDS (type) = namefield;
9343 ggc_add_tree_root (&type, 1);
9351 /* Build Vardesc type. */
9353 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9355 ffecom_type_vardesc_ ()
9357 static tree type = NULL_TREE;
9358 static tree namefield, addrfield, dimsfield, typefield;
9360 if (type == NULL_TREE)
9362 type = make_node (RECORD_TYPE);
9364 namefield = ffecom_decl_field (type, NULL_TREE, "name",
9366 addrfield = ffecom_decl_field (type, namefield, "addr",
9368 dimsfield = ffecom_decl_field (type, addrfield, "dims",
9369 ffecom_f2c_ptr_to_ftnlen_type_node);
9370 typefield = ffecom_decl_field (type, dimsfield, "type",
9373 TYPE_FIELDS (type) = namefield;
9376 ggc_add_tree_root (&type, 1);
9384 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9386 ffecom_vardesc_ (ffebld expr)
9390 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
9391 s = ffebld_symter (expr);
9393 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
9396 tree vardesctype = ffecom_type_vardesc_ ();
9404 static int mynumber = 0;
9406 var = build_decl (VAR_DECL,
9407 ffecom_get_invented_identifier ("__g77_vardesc_%d",
9410 TREE_STATIC (var) = 1;
9411 DECL_INITIAL (var) = error_mark_node;
9413 var = start_decl (var, FALSE);
9415 /* Process inits. */
9417 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
9419 ffesymbol_text (s));
9420 TREE_TYPE (nameinit)
9421 = build_type_variant
9424 build_range_type (integer_type_node,
9426 build_int_2 (i, 0))),
9428 TREE_CONSTANT (nameinit) = 1;
9429 TREE_STATIC (nameinit) = 1;
9430 nameinit = ffecom_1 (ADDR_EXPR,
9431 build_pointer_type (TREE_TYPE (nameinit)),
9434 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
9436 dimsinit = ffecom_vardesc_dims_ (s);
9438 if (typeinit == NULL_TREE)
9440 ffeinfoBasictype bt = ffesymbol_basictype (s);
9441 ffeinfoKindtype kt = ffesymbol_kindtype (s);
9442 int tc = ffecom_f2c_typecode (bt, kt);
9445 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
9448 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
9450 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
9452 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
9454 TREE_CHAIN (TREE_CHAIN (varinits))
9455 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
9456 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
9457 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
9459 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
9460 TREE_CONSTANT (varinits) = 1;
9461 TREE_STATIC (varinits) = 1;
9463 finish_decl (var, varinits, FALSE);
9465 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
9467 ffesymbol_hook (s).vardesc_tree = var;
9470 return ffesymbol_hook (s).vardesc_tree;
9474 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9476 ffecom_vardesc_array_ (ffesymbol s)
9480 tree item = NULL_TREE;
9483 static int mynumber = 0;
9485 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
9487 b = ffebld_trail (b), ++i)
9491 t = ffecom_vardesc_ (ffebld_head (b));
9493 if (list == NULL_TREE)
9494 list = item = build_tree_list (NULL_TREE, t);
9497 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9498 item = TREE_CHAIN (item);
9502 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9503 build_range_type (integer_type_node,
9505 build_int_2 (i, 0)));
9506 list = build (CONSTRUCTOR, item, NULL_TREE, list);
9507 TREE_CONSTANT (list) = 1;
9508 TREE_STATIC (list) = 1;
9510 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber++);
9511 var = build_decl (VAR_DECL, var, item);
9512 TREE_STATIC (var) = 1;
9513 DECL_INITIAL (var) = error_mark_node;
9514 var = start_decl (var, FALSE);
9515 finish_decl (var, list, FALSE);
9521 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9523 ffecom_vardesc_dims_ (ffesymbol s)
9525 if (ffesymbol_dims (s) == NULL)
9526 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
9534 tree item = NULL_TREE;
9538 tree baseoff = NULL_TREE;
9539 static int mynumber = 0;
9541 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
9542 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
9544 numelem = ffecom_expr (ffesymbol_arraysize (s));
9545 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
9548 backlist = NULL_TREE;
9549 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
9551 b = ffebld_trail (b), e = ffebld_trail (e))
9557 if (ffebld_trail (b) == NULL)
9561 t = convert (ffecom_f2c_ftnlen_type_node,
9562 ffecom_expr (ffebld_head (e)));
9564 if (list == NULL_TREE)
9565 list = item = build_tree_list (NULL_TREE, t);
9568 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
9569 item = TREE_CHAIN (item);
9573 if (ffebld_left (ffebld_head (b)) == NULL)
9574 low = ffecom_integer_one_node;
9576 low = ffecom_expr (ffebld_left (ffebld_head (b)));
9577 low = convert (ffecom_f2c_ftnlen_type_node, low);
9579 back = build_tree_list (low, t);
9580 TREE_CHAIN (back) = backlist;
9584 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
9586 if (TREE_VALUE (item) == NULL_TREE)
9587 baseoff = TREE_PURPOSE (item);
9589 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
9590 TREE_PURPOSE (item),
9591 ffecom_2 (MULT_EXPR,
9592 ffecom_f2c_ftnlen_type_node,
9597 /* backlist now dead, along with all TREE_PURPOSEs on it. */
9599 baseoff = build_tree_list (NULL_TREE, baseoff);
9600 TREE_CHAIN (baseoff) = list;
9602 numelem = build_tree_list (NULL_TREE, numelem);
9603 TREE_CHAIN (numelem) = baseoff;
9605 numdim = build_tree_list (NULL_TREE, numdim);
9606 TREE_CHAIN (numdim) = numelem;
9608 item = build_array_type (ffecom_f2c_ftnlen_type_node,
9609 build_range_type (integer_type_node,
9612 ((int) ffesymbol_rank (s)
9614 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
9615 TREE_CONSTANT (list) = 1;
9616 TREE_STATIC (list) = 1;
9618 var = ffecom_get_invented_identifier ("__g77_dims_%d", mynumber++);
9619 var = build_decl (VAR_DECL, var, item);
9620 TREE_STATIC (var) = 1;
9621 DECL_INITIAL (var) = error_mark_node;
9622 var = start_decl (var, FALSE);
9623 finish_decl (var, list, FALSE);
9625 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
9632 /* Essentially does a "fold (build1 (code, type, node))" while checking
9633 for certain housekeeping things.
9635 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9636 ffecom_1_fn instead. */
9638 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9640 ffecom_1 (enum tree_code code, tree type, tree node)
9644 if ((node == error_mark_node)
9645 || (type == error_mark_node))
9646 return error_mark_node;
9648 if (code == ADDR_EXPR)
9650 if (!mark_addressable (node))
9651 assert ("can't mark_addressable this node!" == NULL);
9654 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9659 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
9663 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
9668 if (TREE_CODE (type) != RECORD_TYPE)
9670 item = build1 (code, type, node);
9673 node = ffecom_stabilize_aggregate_ (node);
9674 realtype = TREE_TYPE (TYPE_FIELDS (type));
9676 ffecom_2 (COMPLEX_EXPR, type,
9677 ffecom_1 (NEGATE_EXPR, realtype,
9678 ffecom_1 (REALPART_EXPR, realtype,
9680 ffecom_1 (NEGATE_EXPR, realtype,
9681 ffecom_1 (IMAGPART_EXPR, realtype,
9686 item = build1 (code, type, node);
9690 if (TREE_SIDE_EFFECTS (node))
9691 TREE_SIDE_EFFECTS (item) = 1;
9692 if ((code == ADDR_EXPR) && staticp (node))
9693 TREE_CONSTANT (item) = 1;
9698 /* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9699 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9700 does not set TREE_ADDRESSABLE (because calling an inline
9701 function does not mean the function needs to be separately
9704 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9706 ffecom_1_fn (tree node)
9711 if (node == error_mark_node)
9712 return error_mark_node;
9714 type = build_type_variant (TREE_TYPE (node),
9715 TREE_READONLY (node),
9716 TREE_THIS_VOLATILE (node));
9717 item = build1 (ADDR_EXPR,
9718 build_pointer_type (type), node);
9719 if (TREE_SIDE_EFFECTS (node))
9720 TREE_SIDE_EFFECTS (item) = 1;
9722 TREE_CONSTANT (item) = 1;
9727 /* Essentially does a "fold (build (code, type, node1, node2))" while
9728 checking for certain housekeeping things. */
9730 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9732 ffecom_2 (enum tree_code code, tree type, tree node1,
9737 if ((node1 == error_mark_node)
9738 || (node2 == error_mark_node)
9739 || (type == error_mark_node))
9740 return error_mark_node;
9742 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
9744 tree a, b, c, d, realtype;
9747 assert ("no CONJ_EXPR support yet" == NULL);
9748 return error_mark_node;
9751 item = build_tree_list (TYPE_FIELDS (type), node1);
9752 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
9753 item = build (CONSTRUCTOR, type, NULL_TREE, item);
9757 if (TREE_CODE (type) != RECORD_TYPE)
9759 item = build (code, type, node1, node2);
9762 node1 = ffecom_stabilize_aggregate_ (node1);
9763 node2 = ffecom_stabilize_aggregate_ (node2);
9764 realtype = TREE_TYPE (TYPE_FIELDS (type));
9766 ffecom_2 (COMPLEX_EXPR, type,
9767 ffecom_2 (PLUS_EXPR, realtype,
9768 ffecom_1 (REALPART_EXPR, realtype,
9770 ffecom_1 (REALPART_EXPR, realtype,
9772 ffecom_2 (PLUS_EXPR, realtype,
9773 ffecom_1 (IMAGPART_EXPR, realtype,
9775 ffecom_1 (IMAGPART_EXPR, realtype,
9780 if (TREE_CODE (type) != RECORD_TYPE)
9782 item = build (code, type, node1, node2);
9785 node1 = ffecom_stabilize_aggregate_ (node1);
9786 node2 = ffecom_stabilize_aggregate_ (node2);
9787 realtype = TREE_TYPE (TYPE_FIELDS (type));
9789 ffecom_2 (COMPLEX_EXPR, type,
9790 ffecom_2 (MINUS_EXPR, realtype,
9791 ffecom_1 (REALPART_EXPR, realtype,
9793 ffecom_1 (REALPART_EXPR, realtype,
9795 ffecom_2 (MINUS_EXPR, realtype,
9796 ffecom_1 (IMAGPART_EXPR, realtype,
9798 ffecom_1 (IMAGPART_EXPR, realtype,
9803 if (TREE_CODE (type) != RECORD_TYPE)
9805 item = build (code, type, node1, node2);
9808 node1 = ffecom_stabilize_aggregate_ (node1);
9809 node2 = ffecom_stabilize_aggregate_ (node2);
9810 realtype = TREE_TYPE (TYPE_FIELDS (type));
9811 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9813 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9815 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
9817 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
9820 ffecom_2 (COMPLEX_EXPR, type,
9821 ffecom_2 (MINUS_EXPR, realtype,
9822 ffecom_2 (MULT_EXPR, realtype,
9825 ffecom_2 (MULT_EXPR, realtype,
9828 ffecom_2 (PLUS_EXPR, realtype,
9829 ffecom_2 (MULT_EXPR, realtype,
9832 ffecom_2 (MULT_EXPR, realtype,
9838 if ((TREE_CODE (node1) != RECORD_TYPE)
9839 && (TREE_CODE (node2) != RECORD_TYPE))
9841 item = build (code, type, node1, node2);
9844 assert (TREE_CODE (node1) == RECORD_TYPE);
9845 assert (TREE_CODE (node2) == RECORD_TYPE);
9846 node1 = ffecom_stabilize_aggregate_ (node1);
9847 node2 = ffecom_stabilize_aggregate_ (node2);
9848 realtype = TREE_TYPE (TYPE_FIELDS (type));
9850 ffecom_2 (TRUTH_ANDIF_EXPR, type,
9851 ffecom_2 (code, type,
9852 ffecom_1 (REALPART_EXPR, realtype,
9854 ffecom_1 (REALPART_EXPR, realtype,
9856 ffecom_2 (code, type,
9857 ffecom_1 (IMAGPART_EXPR, realtype,
9859 ffecom_1 (IMAGPART_EXPR, realtype,
9864 if ((TREE_CODE (node1) != RECORD_TYPE)
9865 && (TREE_CODE (node2) != RECORD_TYPE))
9867 item = build (code, type, node1, node2);
9870 assert (TREE_CODE (node1) == RECORD_TYPE);
9871 assert (TREE_CODE (node2) == RECORD_TYPE);
9872 node1 = ffecom_stabilize_aggregate_ (node1);
9873 node2 = ffecom_stabilize_aggregate_ (node2);
9874 realtype = TREE_TYPE (TYPE_FIELDS (type));
9876 ffecom_2 (TRUTH_ORIF_EXPR, type,
9877 ffecom_2 (code, type,
9878 ffecom_1 (REALPART_EXPR, realtype,
9880 ffecom_1 (REALPART_EXPR, realtype,
9882 ffecom_2 (code, type,
9883 ffecom_1 (IMAGPART_EXPR, realtype,
9885 ffecom_1 (IMAGPART_EXPR, realtype,
9890 item = build (code, type, node1, node2);
9894 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
9895 TREE_SIDE_EFFECTS (item) = 1;
9900 /* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
9902 ffesymbol s; // the ENTRY point itself
9903 if (ffecom_2pass_advise_entrypoint(s))
9904 // the ENTRY point has been accepted
9906 Does whatever compiler needs to do when it learns about the entrypoint,
9907 like determine the return type of the master function, count the
9908 number of entrypoints, etc. Returns FALSE if the return type is
9909 not compatible with the return type(s) of other entrypoint(s).
9911 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
9912 later (after _finish_progunit) be called with the same entrypoint(s)
9913 as passed to this fn for which TRUE was returned.
9916 Return FALSE if the return type conflicts with previous entrypoints. */
9918 #if FFECOM_targetCURRENT == FFECOM_targetGCC
9920 ffecom_2pass_advise_entrypoint (ffesymbol entry)
9922 ffebld list; /* opITEM. */
9923 ffebld mlist; /* opITEM. */
9924 ffebld plist; /* opITEM. */
9925 ffebld arg; /* ffebld_head(opITEM). */
9926 ffebld item; /* opITEM. */
9927 ffesymbol s; /* ffebld_symter(arg). */
9928 ffeinfoBasictype bt = ffesymbol_basictype (entry);
9929 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
9930 ffetargetCharacterSize size = ffesymbol_size (entry);
9933 if (ffecom_num_entrypoints_ == 0)
9934 { /* First entrypoint, make list of main
9935 arglist's dummies. */
9936 assert (ffecom_primary_entry_ != NULL);
9938 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
9939 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
9940 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
9942 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
9944 list = ffebld_trail (list))
9946 arg = ffebld_head (list);
9947 if (ffebld_op (arg) != FFEBLD_opSYMTER)
9948 continue; /* Alternate return or some such thing. */
9949 item = ffebld_new_item (arg, NULL);
9951 ffecom_master_arglist_ = item;
9953 ffebld_set_trail (plist, item);
9958 /* If necessary, scan entry arglist for alternate returns. Do this scan
9959 apparently redundantly (it's done below to UNIONize the arglists) so
9960 that we don't complain about RETURN 1 if an offending ENTRY is the only
9961 one with an alternate return. */
9963 if (!ffecom_is_altreturning_)
9965 for (list = ffesymbol_dummyargs (entry);
9967 list = ffebld_trail (list))
9969 arg = ffebld_head (list);
9970 if (ffebld_op (arg) == FFEBLD_opSTAR)
9972 ffecom_is_altreturning_ = TRUE;
9978 /* Now check type compatibility. */
9980 switch (ffecom_master_bt_)
9982 case FFEINFO_basictypeNONE:
9983 ok = (bt != FFEINFO_basictypeCHARACTER);
9986 case FFEINFO_basictypeCHARACTER:
9988 = (bt == FFEINFO_basictypeCHARACTER)
9989 && (kt == ffecom_master_kt_)
9990 && (size == ffecom_master_size_);
9993 case FFEINFO_basictypeANY:
9994 return FALSE; /* Just don't bother. */
9997 if (bt == FFEINFO_basictypeCHARACTER)
10003 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
10005 ffecom_master_bt_ = FFEINFO_basictypeNONE;
10006 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
10013 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
10014 ffest_ffebad_here_current_stmt (0);
10016 return FALSE; /* Can't handle entrypoint. */
10019 /* Entrypoint type compatible with previous types. */
10021 ++ffecom_num_entrypoints_;
10023 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
10025 for (list = ffesymbol_dummyargs (entry);
10027 list = ffebld_trail (list))
10029 arg = ffebld_head (list);
10030 if (ffebld_op (arg) != FFEBLD_opSYMTER)
10031 continue; /* Alternate return or some such thing. */
10032 s = ffebld_symter (arg);
10033 for (plist = NULL, mlist = ffecom_master_arglist_;
10035 plist = mlist, mlist = ffebld_trail (mlist))
10036 { /* plist points to previous item for easy
10037 appending of arg. */
10038 if (ffebld_symter (ffebld_head (mlist)) == s)
10039 break; /* Already have this arg in the master list. */
10042 continue; /* Already have this arg in the master list. */
10044 /* Append this arg to the master list. */
10046 item = ffebld_new_item (arg, NULL);
10048 ffecom_master_arglist_ = item;
10050 ffebld_set_trail (plist, item);
10057 /* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
10059 ffesymbol s; // the ENTRY point itself
10060 ffecom_2pass_do_entrypoint(s);
10062 Does whatever compiler needs to do to make the entrypoint actually
10063 happen. Must be called for each entrypoint after
10064 ffecom_finish_progunit is called. */
10066 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10068 ffecom_2pass_do_entrypoint (ffesymbol entry)
10070 static int mfn_num = 0;
10071 static int ent_num;
10073 if (mfn_num != ffecom_num_fns_)
10074 { /* First entrypoint for this program unit. */
10076 mfn_num = ffecom_num_fns_;
10077 ffecom_do_entry_ (ffecom_primary_entry_, 0);
10082 --ffecom_num_entrypoints_;
10084 ffecom_do_entry_ (entry, ent_num);
10089 /* Essentially does a "fold (build (code, type, node1, node2))" while
10090 checking for certain housekeeping things. Always sets
10091 TREE_SIDE_EFFECTS. */
10093 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10095 ffecom_2s (enum tree_code code, tree type, tree node1,
10100 if ((node1 == error_mark_node)
10101 || (node2 == error_mark_node)
10102 || (type == error_mark_node))
10103 return error_mark_node;
10105 item = build (code, type, node1, node2);
10106 TREE_SIDE_EFFECTS (item) = 1;
10107 return fold (item);
10111 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10112 checking for certain housekeeping things. */
10114 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10116 ffecom_3 (enum tree_code code, tree type, tree node1,
10117 tree node2, tree node3)
10121 if ((node1 == error_mark_node)
10122 || (node2 == error_mark_node)
10123 || (node3 == error_mark_node)
10124 || (type == error_mark_node))
10125 return error_mark_node;
10127 item = build (code, type, node1, node2, node3);
10128 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
10129 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
10130 TREE_SIDE_EFFECTS (item) = 1;
10131 return fold (item);
10135 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
10136 checking for certain housekeeping things. Always sets
10137 TREE_SIDE_EFFECTS. */
10139 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10141 ffecom_3s (enum tree_code code, tree type, tree node1,
10142 tree node2, tree node3)
10146 if ((node1 == error_mark_node)
10147 || (node2 == error_mark_node)
10148 || (node3 == error_mark_node)
10149 || (type == error_mark_node))
10150 return error_mark_node;
10152 item = build (code, type, node1, node2, node3);
10153 TREE_SIDE_EFFECTS (item) = 1;
10154 return fold (item);
10159 /* ffecom_arg_expr -- Transform argument expr into gcc tree
10161 See use by ffecom_list_expr.
10163 If expression is NULL, returns an integer zero tree. If it is not
10164 a CHARACTER expression, returns whatever ffecom_expr
10165 returns and sets the length return value to NULL_TREE. Otherwise
10166 generates code to evaluate the character expression, returns the proper
10167 pointer to the result, but does NOT set the length return value to a tree
10168 that specifies the length of the result. (In other words, the length
10169 variable is always set to NULL_TREE, because a length is never passed.)
10172 Don't set returned length, since nobody needs it (yet; someday if
10173 we allow CHARACTER*(*) dummies to statement functions, we'll need
10176 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10178 ffecom_arg_expr (ffebld expr, tree *length)
10182 *length = NULL_TREE;
10185 return integer_zero_node;
10187 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10188 return ffecom_expr (expr);
10190 return ffecom_arg_ptr_to_expr (expr, &ign);
10194 /* Transform expression into constant argument-pointer-to-expression tree.
10196 If the expression can be transformed into a argument-pointer-to-expression
10197 tree that is constant, that is done, and the tree returned. Else
10198 NULL_TREE is returned.
10200 That way, a caller can attempt to provide compile-time initialization
10201 of a variable and, if that fails, *then* choose to start a new block
10202 and resort to using temporaries, as appropriate. */
10205 ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10208 return integer_zero_node;
10210 if (ffebld_op (expr) == FFEBLD_opANY)
10213 *length = error_mark_node;
10214 return error_mark_node;
10217 if (ffebld_arity (expr) == 0
10218 && (ffebld_op (expr) != FFEBLD_opSYMTER
10219 || ffebld_where (expr) == FFEINFO_whereCOMMON
10220 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10221 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10225 t = ffecom_arg_ptr_to_expr (expr, length);
10226 assert (TREE_CONSTANT (t));
10227 assert (! length || TREE_CONSTANT (*length));
10232 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10233 *length = build_int_2 (ffebld_size (expr), 0);
10235 *length = NULL_TREE;
10239 /* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
10241 See use by ffecom_list_ptr_to_expr.
10243 If expression is NULL, returns an integer zero tree. If it is not
10244 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10245 returns and sets the length return value to NULL_TREE. Otherwise
10246 generates code to evaluate the character expression, returns the proper
10247 pointer to the result, AND sets the length return value to a tree that
10248 specifies the length of the result.
10250 If the length argument is NULL, this is a slightly special
10251 case of building a FORMAT expression, that is, an expression that
10252 will be used at run time without regard to length. For the current
10253 implementation, which uses the libf2c library, this means it is nice
10254 to append a null byte to the end of the expression, where feasible,
10255 to make sure any diagnostic about the FORMAT string terminates at
10258 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10259 length argument. This might even be seen as a feature, if a null
10260 byte can always be appended. */
10262 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10264 ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
10268 ffecomConcatList_ catlist;
10270 if (length != NULL)
10271 *length = NULL_TREE;
10274 return integer_zero_node;
10276 switch (ffebld_op (expr))
10278 case FFEBLD_opPERCENT_VAL:
10279 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10280 return ffecom_expr (ffebld_left (expr));
10285 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10286 if (temp_exp == error_mark_node)
10287 return error_mark_node;
10289 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10293 case FFEBLD_opPERCENT_REF:
10294 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10295 return ffecom_ptr_to_expr (ffebld_left (expr));
10296 if (length != NULL)
10298 ign_length = NULL_TREE;
10299 length = &ign_length;
10301 expr = ffebld_left (expr);
10304 case FFEBLD_opPERCENT_DESCR:
10305 switch (ffeinfo_basictype (ffebld_info (expr)))
10307 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10308 case FFEINFO_basictypeHOLLERITH:
10310 case FFEINFO_basictypeCHARACTER:
10311 break; /* Passed by descriptor anyway. */
10314 item = ffecom_ptr_to_expr (expr);
10315 if (item != error_mark_node)
10316 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
10325 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10326 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10327 && (length != NULL))
10328 { /* Pass Hollerith by descriptor. */
10329 ffetargetHollerith h;
10331 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10332 h = ffebld_cu_val_hollerith (ffebld_constant_union
10333 (ffebld_conter (expr)));
10335 = build_int_2 (h.length, 0);
10336 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10340 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10341 return ffecom_ptr_to_expr (expr);
10343 assert (ffeinfo_kindtype (ffebld_info (expr))
10344 == FFEINFO_kindtypeCHARACTER1);
10346 while (ffebld_op (expr) == FFEBLD_opPAREN)
10347 expr = ffebld_left (expr);
10349 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10350 switch (ffecom_concat_list_count_ (catlist))
10352 case 0: /* Shouldn't happen, but in case it does... */
10353 if (length != NULL)
10355 *length = ffecom_f2c_ftnlen_zero_node;
10356 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10358 ffecom_concat_list_kill_ (catlist);
10359 return null_pointer_node;
10361 case 1: /* The (fairly) easy case. */
10362 if (length == NULL)
10363 ffecom_char_args_with_null_ (&item, &ign_length,
10364 ffecom_concat_list_expr_ (catlist, 0));
10366 ffecom_char_args_ (&item, length,
10367 ffecom_concat_list_expr_ (catlist, 0));
10368 ffecom_concat_list_kill_ (catlist);
10369 assert (item != NULL_TREE);
10372 default: /* Must actually concatenate things. */
10377 int count = ffecom_concat_list_count_ (catlist);
10388 ffetargetCharacterSize sz;
10390 sz = ffecom_concat_list_maxlen_ (catlist);
10392 assert (sz != FFETARGET_charactersizeNONE);
10397 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10398 FFETARGET_charactersizeNONE, count, TRUE);
10401 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10402 FFETARGET_charactersizeNONE, count, TRUE);
10403 temporary = ffecom_push_tempvar (char_type_node,
10409 hook = ffebld_nonter_hook (expr);
10411 assert (TREE_CODE (hook) == TREE_VEC);
10412 assert (TREE_VEC_LENGTH (hook) == 3);
10413 length_array = lengths = TREE_VEC_ELT (hook, 0);
10414 item_array = items = TREE_VEC_ELT (hook, 1);
10415 temporary = TREE_VEC_ELT (hook, 2);
10419 known_length = ffecom_f2c_ftnlen_zero_node;
10421 for (i = 0; i < count; ++i)
10424 && (length == NULL))
10425 ffecom_char_args_with_null_ (&citem, &clength,
10426 ffecom_concat_list_expr_ (catlist, i));
10428 ffecom_char_args_ (&citem, &clength,
10429 ffecom_concat_list_expr_ (catlist, i));
10430 if ((citem == error_mark_node)
10431 || (clength == error_mark_node))
10433 ffecom_concat_list_kill_ (catlist);
10434 *length = error_mark_node;
10435 return error_mark_node;
10439 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10440 ffecom_modify (void_type_node,
10441 ffecom_2 (ARRAY_REF,
10442 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10444 build_int_2 (i, 0)),
10447 clength = ffecom_save_tree (clength);
10448 if (length != NULL)
10450 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10454 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10455 ffecom_modify (void_type_node,
10456 ffecom_2 (ARRAY_REF,
10457 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10459 build_int_2 (i, 0)),
10464 temporary = ffecom_1 (ADDR_EXPR,
10465 build_pointer_type (TREE_TYPE (temporary)),
10468 item = build_tree_list (NULL_TREE, temporary);
10470 = build_tree_list (NULL_TREE,
10471 ffecom_1 (ADDR_EXPR,
10472 build_pointer_type (TREE_TYPE (items)),
10474 TREE_CHAIN (TREE_CHAIN (item))
10475 = build_tree_list (NULL_TREE,
10476 ffecom_1 (ADDR_EXPR,
10477 build_pointer_type (TREE_TYPE (lengths)),
10479 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10482 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10483 convert (ffecom_f2c_ftnlen_type_node,
10484 build_int_2 (count, 0))));
10485 num = build_int_2 (sz, 0);
10486 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10487 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10488 = build_tree_list (NULL_TREE, num);
10490 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
10491 TREE_SIDE_EFFECTS (item) = 1;
10492 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10496 if (length != NULL)
10497 *length = known_length;
10500 ffecom_concat_list_kill_ (catlist);
10501 assert (item != NULL_TREE);
10506 /* Generate call to run-time function.
10508 The first arg is the GNU Fortran Run-Time function index, the second
10509 arg is the list of arguments to pass to it. Returned is the expression
10510 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10511 result (which may be void). */
10513 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10515 ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
10517 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10518 ffecom_gfrt_kindtype (ix),
10519 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10520 NULL_TREE, args, NULL_TREE, NULL,
10521 NULL, NULL_TREE, TRUE, hook);
10525 /* Transform constant-union to tree. */
10527 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10529 ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10530 ffeinfoKindtype kt, tree tree_type)
10536 case FFEINFO_basictypeINTEGER:
10542 #if FFETARGET_okINTEGER1
10543 case FFEINFO_kindtypeINTEGER1:
10544 val = ffebld_cu_val_integer1 (*cu);
10548 #if FFETARGET_okINTEGER2
10549 case FFEINFO_kindtypeINTEGER2:
10550 val = ffebld_cu_val_integer2 (*cu);
10554 #if FFETARGET_okINTEGER3
10555 case FFEINFO_kindtypeINTEGER3:
10556 val = ffebld_cu_val_integer3 (*cu);
10560 #if FFETARGET_okINTEGER4
10561 case FFEINFO_kindtypeINTEGER4:
10562 val = ffebld_cu_val_integer4 (*cu);
10567 assert ("bad INTEGER constant kind type" == NULL);
10568 /* Fall through. */
10569 case FFEINFO_kindtypeANY:
10570 return error_mark_node;
10572 item = build_int_2 (val, (val < 0) ? -1 : 0);
10573 TREE_TYPE (item) = tree_type;
10577 case FFEINFO_basictypeLOGICAL:
10583 #if FFETARGET_okLOGICAL1
10584 case FFEINFO_kindtypeLOGICAL1:
10585 val = ffebld_cu_val_logical1 (*cu);
10589 #if FFETARGET_okLOGICAL2
10590 case FFEINFO_kindtypeLOGICAL2:
10591 val = ffebld_cu_val_logical2 (*cu);
10595 #if FFETARGET_okLOGICAL3
10596 case FFEINFO_kindtypeLOGICAL3:
10597 val = ffebld_cu_val_logical3 (*cu);
10601 #if FFETARGET_okLOGICAL4
10602 case FFEINFO_kindtypeLOGICAL4:
10603 val = ffebld_cu_val_logical4 (*cu);
10608 assert ("bad LOGICAL constant kind type" == NULL);
10609 /* Fall through. */
10610 case FFEINFO_kindtypeANY:
10611 return error_mark_node;
10613 item = build_int_2 (val, (val < 0) ? -1 : 0);
10614 TREE_TYPE (item) = tree_type;
10618 case FFEINFO_basictypeREAL:
10620 REAL_VALUE_TYPE val;
10624 #if FFETARGET_okREAL1
10625 case FFEINFO_kindtypeREAL1:
10626 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10630 #if FFETARGET_okREAL2
10631 case FFEINFO_kindtypeREAL2:
10632 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10636 #if FFETARGET_okREAL3
10637 case FFEINFO_kindtypeREAL3:
10638 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10642 #if FFETARGET_okREAL4
10643 case FFEINFO_kindtypeREAL4:
10644 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10649 assert ("bad REAL constant kind type" == NULL);
10650 /* Fall through. */
10651 case FFEINFO_kindtypeANY:
10652 return error_mark_node;
10654 item = build_real (tree_type, val);
10658 case FFEINFO_basictypeCOMPLEX:
10660 REAL_VALUE_TYPE real;
10661 REAL_VALUE_TYPE imag;
10662 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
10666 #if FFETARGET_okCOMPLEX1
10667 case FFEINFO_kindtypeREAL1:
10668 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10669 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10673 #if FFETARGET_okCOMPLEX2
10674 case FFEINFO_kindtypeREAL2:
10675 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10676 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10680 #if FFETARGET_okCOMPLEX3
10681 case FFEINFO_kindtypeREAL3:
10682 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10683 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10687 #if FFETARGET_okCOMPLEX4
10688 case FFEINFO_kindtypeREAL4:
10689 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10690 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10695 assert ("bad REAL constant kind type" == NULL);
10696 /* Fall through. */
10697 case FFEINFO_kindtypeANY:
10698 return error_mark_node;
10700 item = ffecom_build_complex_constant_ (tree_type,
10701 build_real (el_type, real),
10702 build_real (el_type, imag));
10706 case FFEINFO_basictypeCHARACTER:
10707 { /* Happens only in DATA and similar contexts. */
10708 ffetargetCharacter1 val;
10712 #if FFETARGET_okCHARACTER1
10713 case FFEINFO_kindtypeLOGICAL1:
10714 val = ffebld_cu_val_character1 (*cu);
10719 assert ("bad CHARACTER constant kind type" == NULL);
10720 /* Fall through. */
10721 case FFEINFO_kindtypeANY:
10722 return error_mark_node;
10724 item = build_string (ffetarget_length_character1 (val),
10725 ffetarget_text_character1 (val));
10727 = build_type_variant (build_array_type (char_type_node,
10729 (integer_type_node,
10732 (ffetarget_length_character1
10738 case FFEINFO_basictypeHOLLERITH:
10740 ffetargetHollerith h;
10742 h = ffebld_cu_val_hollerith (*cu);
10744 /* If not at least as wide as default INTEGER, widen it. */
10745 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10746 item = build_string (h.length, h.text);
10749 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
10751 memcpy (str, h.text, h.length);
10752 memset (&str[h.length], ' ',
10753 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10755 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10759 = build_type_variant (build_array_type (char_type_node,
10761 (integer_type_node,
10769 case FFEINFO_basictypeTYPELESS:
10771 ffetargetInteger1 ival;
10772 ffetargetTypeless tless;
10775 tless = ffebld_cu_val_typeless (*cu);
10776 error = ffetarget_convert_integer1_typeless (&ival, tless);
10777 assert (error == FFEBAD);
10779 item = build_int_2 ((int) ival, 0);
10784 assert ("not yet on constant type" == NULL);
10785 /* Fall through. */
10786 case FFEINFO_basictypeANY:
10787 return error_mark_node;
10790 TREE_CONSTANT (item) = 1;
10797 /* Transform expression into constant tree.
10799 If the expression can be transformed into a tree that is constant,
10800 that is done, and the tree returned. Else NULL_TREE is returned.
10802 That way, a caller can attempt to provide compile-time initialization
10803 of a variable and, if that fails, *then* choose to start a new block
10804 and resort to using temporaries, as appropriate. */
10807 ffecom_const_expr (ffebld expr)
10810 return integer_zero_node;
10812 if (ffebld_op (expr) == FFEBLD_opANY)
10813 return error_mark_node;
10815 if (ffebld_arity (expr) == 0
10816 && (ffebld_op (expr) != FFEBLD_opSYMTER
10818 /* ~~Enable once common/equivalence is handled properly? */
10819 || ffebld_where (expr) == FFEINFO_whereCOMMON
10821 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10822 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10826 t = ffecom_expr (expr);
10827 assert (TREE_CONSTANT (t));
10834 /* Handy way to make a field in a struct/union. */
10836 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10838 ffecom_decl_field (tree context, tree prevfield,
10839 const char *name, tree type)
10843 field = build_decl (FIELD_DECL, get_identifier (name), type);
10844 DECL_CONTEXT (field) = context;
10845 DECL_ALIGN (field) = 0;
10846 DECL_USER_ALIGN (field) = 0;
10847 if (prevfield != NULL_TREE)
10848 TREE_CHAIN (prevfield) = field;
10856 ffecom_close_include (FILE *f)
10858 #if FFECOM_GCC_INCLUDE
10859 ffecom_close_include_ (f);
10864 ffecom_decode_include_option (char *spec)
10866 #if FFECOM_GCC_INCLUDE
10867 return ffecom_decode_include_option_ (spec);
10873 /* End a compound statement (block). */
10875 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10877 ffecom_end_compstmt (void)
10879 return bison_rule_compstmt_ ();
10881 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
10883 /* ffecom_end_transition -- Perform end transition on all symbols
10885 ffecom_end_transition();
10887 Calls ffecom_sym_end_transition for each global and local symbol. */
10890 ffecom_end_transition ()
10892 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10896 if (ffe_is_ffedebug ())
10897 fprintf (dmpout, "; end_stmt_transition\n");
10899 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10900 ffecom_list_blockdata_ = NULL;
10901 ffecom_list_common_ = NULL;
10904 ffesymbol_drive (ffecom_sym_end_transition);
10905 if (ffe_is_ffedebug ())
10907 ffestorag_report ();
10908 #if FFECOM_targetCURRENT == FFECOM_targetFFE
10909 ffesymbol_report_all ();
10913 #if FFECOM_targetCURRENT == FFECOM_targetGCC
10914 ffecom_start_progunit_ ();
10916 for (item = ffecom_list_blockdata_;
10918 item = ffebld_trail (item))
10925 static int number = 0;
10927 callee = ffebld_head (item);
10928 s = ffebld_symter (callee);
10929 t = ffesymbol_hook (s).decl_tree;
10930 if (t == NULL_TREE)
10932 s = ffecom_sym_transform_ (s);
10933 t = ffesymbol_hook (s).decl_tree;
10936 dt = build_pointer_type (TREE_TYPE (t));
10938 var = build_decl (VAR_DECL,
10939 ffecom_get_invented_identifier ("__g77_forceload_%d",
10942 DECL_EXTERNAL (var) = 0;
10943 TREE_STATIC (var) = 1;
10944 TREE_PUBLIC (var) = 0;
10945 DECL_INITIAL (var) = error_mark_node;
10946 TREE_USED (var) = 1;
10948 var = start_decl (var, FALSE);
10950 t = ffecom_1 (ADDR_EXPR, dt, t);
10952 finish_decl (var, t, FALSE);
10955 /* This handles any COMMON areas that weren't referenced but have, for
10956 example, important initial data. */
10958 for (item = ffecom_list_common_;
10960 item = ffebld_trail (item))
10961 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
10963 ffecom_list_common_ = NULL;
10967 /* ffecom_exec_transition -- Perform exec transition on all symbols
10969 ffecom_exec_transition();
10971 Calls ffecom_sym_exec_transition for each global and local symbol.
10972 Make sure error updating not inhibited. */
10975 ffecom_exec_transition ()
10979 if (ffe_is_ffedebug ())
10980 fprintf (dmpout, "; exec_stmt_transition\n");
10982 inhibited = ffebad_inhibit ();
10983 ffebad_set_inhibit (FALSE);
10985 ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */
10986 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
10987 if (ffe_is_ffedebug ())
10989 ffestorag_report ();
10990 #if FFECOM_targetCURRENT == FFECOM_targetFFE
10991 ffesymbol_report_all ();
10996 ffebad_set_inhibit (TRUE);
10999 /* Handle assignment statement.
11001 Convert dest and source using ffecom_expr, then join them
11002 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
11004 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11006 ffecom_expand_let_stmt (ffebld dest, ffebld source)
11013 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
11018 /* This attempts to replicate the test below, but must not be
11019 true when the test below is false. (Always err on the side
11020 of creating unused temporaries, to avoid ICEs.) */
11021 if (ffebld_op (dest) != FFEBLD_opSYMTER
11022 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
11023 && (TREE_CODE (dest_tree) != VAR_DECL
11024 || TREE_ADDRESSABLE (dest_tree))))
11026 ffecom_prepare_expr_ (source, dest);
11031 ffecom_prepare_expr_ (source, NULL);
11035 ffecom_prepare_expr_w (NULL_TREE, dest);
11037 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
11038 create a temporary through which the assignment is to take place,
11039 since MODIFY_EXPR doesn't handle partial overlap properly. */
11040 if (ffebld_basictype (dest) == FFEINFO_basictypeCOMPLEX
11041 && ffecom_possible_partial_overlap_ (dest, source))
11043 assign_temp = ffecom_make_tempvar ("complex_let",
11045 [ffebld_basictype (dest)]
11046 [ffebld_kindtype (dest)],
11047 FFETARGET_charactersizeNONE,
11051 assign_temp = NULL_TREE;
11053 ffecom_prepare_end ();
11055 dest_tree = ffecom_expr_w (NULL_TREE, dest);
11056 if (dest_tree == error_mark_node)
11059 if ((TREE_CODE (dest_tree) != VAR_DECL)
11060 || TREE_ADDRESSABLE (dest_tree))
11061 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
11065 assert (! dest_used);
11067 source_tree = ffecom_expr (source);
11069 if (source_tree == error_mark_node)
11073 expr_tree = source_tree;
11074 else if (assign_temp)
11077 /* The back end understands a conceptual move (evaluate source;
11078 store into dest), so use that, in case it can determine
11079 that it is going to use, say, two registers as temporaries
11080 anyway. So don't use the temp (and someday avoid generating
11081 it, once this code starts triggering regularly). */
11082 expr_tree = ffecom_2s (MOVE_EXPR, void_type_node,
11086 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11089 expand_expr_stmt (expr_tree);
11090 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11096 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
11100 expand_expr_stmt (expr_tree);
11104 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
11105 ffecom_prepare_expr_w (NULL_TREE, dest);
11107 ffecom_prepare_end ();
11109 ffecom_char_args_ (&dest_tree, &dest_length, dest);
11110 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
11115 /* ffecom_expr -- Transform expr into gcc tree
11118 ffebld expr; // FFE expression.
11119 tree = ffecom_expr(expr);
11121 Recursive descent on expr while making corresponding tree nodes and
11122 attaching type info and such. */
11124 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11126 ffecom_expr (ffebld expr)
11128 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
11132 /* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
11134 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11136 ffecom_expr_assign (ffebld expr)
11138 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11142 /* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
11144 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11146 ffecom_expr_assign_w (ffebld expr)
11148 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
11152 /* Transform expr for use as into read/write tree and stabilize the
11153 reference. Not for use on CHARACTER expressions.
11155 Recursive descent on expr while making corresponding tree nodes and
11156 attaching type info and such. */
11158 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11160 ffecom_expr_rw (tree type, ffebld expr)
11162 assert (expr != NULL);
11163 /* Different target types not yet supported. */
11164 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11166 return stabilize_reference (ffecom_expr (expr));
11170 /* Transform expr for use as into write tree and stabilize the
11171 reference. Not for use on CHARACTER expressions.
11173 Recursive descent on expr while making corresponding tree nodes and
11174 attaching type info and such. */
11176 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11178 ffecom_expr_w (tree type, ffebld expr)
11180 assert (expr != NULL);
11181 /* Different target types not yet supported. */
11182 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11184 return stabilize_reference (ffecom_expr (expr));
11188 /* Do global stuff. */
11190 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11192 ffecom_finish_compile ()
11194 assert (ffecom_outer_function_decl_ == NULL_TREE);
11195 assert (current_function_decl == NULL_TREE);
11197 ffeglobal_drive (ffecom_finish_global_);
11201 /* Public entry point for front end to access finish_decl. */
11203 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11205 ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11207 assert (!is_top_level);
11208 finish_decl (decl, init, FALSE);
11212 /* Finish a program unit. */
11214 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11216 ffecom_finish_progunit ()
11218 ffecom_end_compstmt ();
11220 ffecom_previous_function_decl_ = current_function_decl;
11221 ffecom_which_entrypoint_decl_ = NULL_TREE;
11223 finish_function (0);
11228 /* Wrapper for get_identifier. pattern is sprintf-like. */
11230 #if FFECOM_targetCURRENT == FFECOM_targetGCC
11232 ffecom_get_invented_identifier (const char *pattern, ...)
11238 va_start (ap, pattern);
11239 if (vasprintf (&nam, pattern, ap) == 0)
11242 decl = get_identifier (nam);
11244 IDENTIFIER_INVENTED (decl) = 1;
11249 ffecom_gfrt_basictype (ffecomGfrt gfrt)
11251 assert (gfrt < FFECOM_gfrt);
11253 switch (ffecom_gfrt_type_[gfrt])
11255 case FFECOM_rttypeVOID_:
11256 case FFECOM_rttypeVOIDSTAR_:
11257 return FFEINFO_basictypeNONE;
11259 case FFECOM_rttypeFTNINT_:
11260 return FFEINFO_basictypeINTEGER;
11262 case FFECOM_rttypeINTEGER_:
11263 return FFEINFO_basictypeINTEGER;
11265 case FFECOM_rttypeLONGINT_:
11266 return FFEINFO_basictypeINTEGER;
11268 case FFECOM_rttypeLOGICAL_:
11269 return FFEINFO_basictypeLOGICAL;
11271 case FFECOM_rttypeREAL_F2C_:
11272 case FFECOM_rttypeREAL_GNU_:
11273 return FFEINFO_basictypeREAL;
11275 case FFECOM_rttypeCOMPLEX_F2C_:
11276 case FFECOM_rttypeCOMPLEX_GNU_:
11277 return FFEINFO_basictypeCOMPLEX;
11279 case FFECOM_rttypeDOUBLE_:
11280 case FFECOM_rttypeDOUBLEREAL_:
11281 return FFEINFO_basictypeREAL;
11283 case FFECOM_rttypeDBLCMPLX_F2C_:
11284 case FFECOM_rttypeDBLCMPLX_GNU_:
11285 return FFEINFO_basictypeCOMPLEX;
11287 case FFECOM_rttypeCHARACTER_:
11288 return FFEINFO_basictypeCHARACTER;
11291 return FFEINFO_basictypeANY;
11296 ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11298 assert (gfrt < FFECOM_gfrt);
11300 switch (ffecom_gfrt_type_[gfrt])
11302 case FFECOM_rttypeVOID_:
11303 case FFECOM_rttypeVOIDSTAR_:
11304 return FFEINFO_kindtypeNONE;
11306 case FFECOM_rttypeFTNINT_:
11307 return FFEINFO_kindtypeINTEGER1;
11309 case FFECOM_rttypeINTEGER_:
11310 return FFEINFO_kindtypeINTEGER1;
11312 case FFECOM_rttypeLONGINT_:
11313 return FFEINFO_kindtypeINTEGER4;
11315 case FFECOM_rttypeLOGICAL_:
11316 return FFEINFO_kindtypeLOGICAL1;
11318 case FFECOM_rttypeREAL_F2C_:
11319 case FFECOM_rttypeREAL_GNU_:
11320 return FFEINFO_kindtypeREAL1;
11322 case FFECOM_rttypeCOMPLEX_F2C_:
11323 case FFECOM_rttypeCOMPLEX_GNU_:
11324 return FFEINFO_kindtypeREAL1;
11326 case FFECOM_rttypeDOUBLE_:
11327 case FFECOM_rttypeDOUBLEREAL_:
11328 return FFEINFO_kindtypeREAL2;
11330 case FFECOM_rttypeDBLCMPLX_F2C_:
11331 case FFECOM_rttypeDBLCMPLX_GNU_:
11332 return FFEINFO_kindtypeREAL2;
11334 case FFECOM_rttypeCHARACTER_:
11335 return FFEINFO_kindtypeCHARACTER1;
11338 return FFEINFO_kindtypeANY;
11352 tree double_ftype_double;
11353 tree float_ftype_float;
11354 tree ldouble_ftype_ldouble;
11355 tree ffecom_tree_ptr_to_fun_type_void;
11357 /* This block of code comes from the now-obsolete cktyps.c. It checks
11358 whether the compiler environment is buggy in known ways, some of which
11359 would, if not explicitly checked here, result in subtle bugs in g77. */
11361 if (ffe_is_do_internal_checks ())
11363 static char names[][12]
11365 {"bar", "bletch", "foo", "foobar"};
11370 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
11371 (int (*)(const void *, const void *)) strcmp);
11372 if (name != (char *) &names[2])
11374 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11379 ul = strtoul ("123456789", NULL, 10);
11380 if (ul != 123456789L)
11382 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11383 in proj.h" == NULL);
11387 fl = atof ("56.789");
11388 if ((fl < 56.788) || (fl > 56.79))
11390 assert ("atof not type double, fix your #include <stdio.h>"
11396 #if FFECOM_GCC_INCLUDE
11397 ffecom_initialize_char_syntax_ ();
11400 ffecom_outer_function_decl_ = NULL_TREE;
11401 current_function_decl = NULL_TREE;
11402 named_labels = NULL_TREE;
11403 current_binding_level = NULL_BINDING_LEVEL;
11404 free_binding_level = NULL_BINDING_LEVEL;
11405 /* Make the binding_level structure for global names. */
11407 global_binding_level = current_binding_level;
11408 current_binding_level->prep_state = 2;
11410 build_common_tree_nodes (1);
11412 /* Define `int' and `char' first so that dbx will output them first. */
11413 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11414 integer_type_node));
11415 /* CHARACTER*1 is unsigned in ICHAR contexts. */
11416 char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
11417 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11419 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11420 long_integer_type_node));
11421 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11422 unsigned_type_node));
11423 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11424 long_unsigned_type_node));
11425 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11426 long_long_integer_type_node));
11427 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11428 long_long_unsigned_type_node));
11429 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11430 short_integer_type_node));
11431 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11432 short_unsigned_type_node));
11434 /* Set the sizetype before we make other types. This *should* be the
11435 first type we create. */
11438 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
11439 ffecom_typesize_pointer_
11440 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype)) / BITS_PER_UNIT;
11442 build_common_tree_nodes_2 (0);
11444 /* Define both `signed char' and `unsigned char'. */
11445 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11446 signed_char_type_node));
11448 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11449 unsigned_char_type_node));
11451 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11453 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11454 double_type_node));
11455 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11456 long_double_type_node));
11458 /* For now, override what build_common_tree_nodes has done. */
11459 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
11460 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11461 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11462 complex_long_double_type_node
11463 = ffecom_make_complex_type_ (long_double_type_node);
11465 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11466 complex_integer_type_node));
11467 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11468 complex_float_type_node));
11469 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11470 complex_double_type_node));
11471 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11472 complex_long_double_type_node));
11474 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11476 /* We are not going to have real types in C with less than byte alignment,
11477 so we might as well not have any types that claim to have it. */
11478 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
11479 TYPE_USER_ALIGN (void_type_node) = 0;
11481 string_type_node = build_pointer_type (char_type_node);
11483 ffecom_tree_fun_type_void
11484 = build_function_type (void_type_node, NULL_TREE);
11486 ffecom_tree_ptr_to_fun_type_void
11487 = build_pointer_type (ffecom_tree_fun_type_void);
11489 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
11492 = build_function_type (float_type_node,
11493 tree_cons (NULL_TREE, float_type_node, endlink));
11495 double_ftype_double
11496 = build_function_type (double_type_node,
11497 tree_cons (NULL_TREE, double_type_node, endlink));
11499 ldouble_ftype_ldouble
11500 = build_function_type (long_double_type_node,
11501 tree_cons (NULL_TREE, long_double_type_node,
11504 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11505 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11507 ffecom_tree_type[i][j] = NULL_TREE;
11508 ffecom_tree_fun_type[i][j] = NULL_TREE;
11509 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11510 ffecom_f2c_typecode_[i][j] = -1;
11513 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11514 to size FLOAT_TYPE_SIZE because they have to be the same size as
11515 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11516 Compiler options and other such stuff that change the ways these
11517 types are set should not affect this particular setup. */
11519 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11520 = t = make_signed_type (FLOAT_TYPE_SIZE);
11521 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11523 type = ffetype_new ();
11525 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11527 ffetype_set_ams (type,
11528 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11529 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11530 ffetype_set_star (base_type,
11531 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11533 ffetype_set_kind (base_type, 1, type);
11534 ffecom_typesize_integer1_ = ffetype_size (type);
11535 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
11537 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11538 = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */
11539 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11542 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11543 = t = make_signed_type (CHAR_TYPE_SIZE);
11544 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11546 type = ffetype_new ();
11547 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11549 ffetype_set_ams (type,
11550 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11551 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11552 ffetype_set_star (base_type,
11553 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11555 ffetype_set_kind (base_type, 3, type);
11556 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
11558 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11559 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11560 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11563 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11564 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11565 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11567 type = ffetype_new ();
11568 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11570 ffetype_set_ams (type,
11571 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11572 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11573 ffetype_set_star (base_type,
11574 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11576 ffetype_set_kind (base_type, 6, type);
11577 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
11579 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11580 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11581 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11584 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11585 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11586 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11588 type = ffetype_new ();
11589 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11591 ffetype_set_ams (type,
11592 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11593 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11594 ffetype_set_star (base_type,
11595 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11597 ffetype_set_kind (base_type, 2, type);
11598 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
11600 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11601 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11602 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11606 if (ffe_is_do_internal_checks ()
11607 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11608 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11609 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11610 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
11612 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11617 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11618 = t = make_signed_type (FLOAT_TYPE_SIZE);
11619 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11621 type = ffetype_new ();
11623 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11625 ffetype_set_ams (type,
11626 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11627 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11628 ffetype_set_star (base_type,
11629 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11631 ffetype_set_kind (base_type, 1, type);
11632 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
11634 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11635 = t = make_signed_type (CHAR_TYPE_SIZE);
11636 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11638 type = ffetype_new ();
11639 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11641 ffetype_set_ams (type,
11642 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11643 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11644 ffetype_set_star (base_type,
11645 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11647 ffetype_set_kind (base_type, 3, type);
11648 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
11650 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11651 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11652 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11654 type = ffetype_new ();
11655 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11657 ffetype_set_ams (type,
11658 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11659 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11660 ffetype_set_star (base_type,
11661 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11663 ffetype_set_kind (base_type, 6, type);
11664 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
11666 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11667 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11668 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11670 type = ffetype_new ();
11671 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11673 ffetype_set_ams (type,
11674 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11675 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11676 ffetype_set_star (base_type,
11677 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11679 ffetype_set_kind (base_type, 2, type);
11680 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
11682 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11683 = t = make_node (REAL_TYPE);
11684 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11685 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11688 type = ffetype_new ();
11690 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11692 ffetype_set_ams (type,
11693 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11694 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11695 ffetype_set_star (base_type,
11696 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11698 ffetype_set_kind (base_type, 1, type);
11699 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11700 = FFETARGET_f2cTYREAL;
11701 assert (ffetype_size (type) == sizeof (ffetargetReal1));
11703 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11704 = t = make_node (REAL_TYPE);
11705 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */
11706 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11709 type = ffetype_new ();
11710 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11712 ffetype_set_ams (type,
11713 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11714 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11715 ffetype_set_star (base_type,
11716 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11718 ffetype_set_kind (base_type, 2, type);
11719 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11720 = FFETARGET_f2cTYDREAL;
11721 assert (ffetype_size (type) == sizeof (ffetargetReal2));
11723 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11724 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11725 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11727 type = ffetype_new ();
11729 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11731 ffetype_set_ams (type,
11732 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11733 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11734 ffetype_set_star (base_type,
11735 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11737 ffetype_set_kind (base_type, 1, type);
11738 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11739 = FFETARGET_f2cTYCOMPLEX;
11740 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
11742 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11743 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11744 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11746 type = ffetype_new ();
11747 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11749 ffetype_set_ams (type,
11750 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11751 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11752 ffetype_set_star (base_type,
11753 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11755 ffetype_set_kind (base_type, 2,
11757 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11758 = FFETARGET_f2cTYDCOMPLEX;
11759 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
11761 /* Make function and ptr-to-function types for non-CHARACTER types. */
11763 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11764 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11766 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11768 if (i == FFEINFO_basictypeINTEGER)
11770 /* Figure out the smallest INTEGER type that can hold
11771 a pointer on this machine. */
11772 if (GET_MODE_SIZE (TYPE_MODE (t))
11773 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11775 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11776 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11777 > GET_MODE_SIZE (TYPE_MODE (t))))
11778 ffecom_pointer_kind_ = j;
11781 else if (i == FFEINFO_basictypeCOMPLEX)
11782 t = void_type_node;
11783 /* For f2c compatibility, REAL functions are really
11784 implemented as DOUBLE PRECISION. */
11785 else if ((i == FFEINFO_basictypeREAL)
11786 && (j == FFEINFO_kindtypeREAL1))
11787 t = ffecom_tree_type
11788 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
11790 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11792 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11796 /* Set up pointer types. */
11798 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
11799 fatal_error ("no INTEGER type can hold a pointer on this configuration");
11800 else if (0 && ffe_is_do_internal_checks ())
11801 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11802 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11803 FFEINFO_kindtypeINTEGERDEFAULT),
11805 ffeinfo_type (FFEINFO_basictypeINTEGER,
11806 ffecom_pointer_kind_));
11808 if (ffe_is_ugly_assign ())
11809 ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */
11811 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11812 if (0 && ffe_is_do_internal_checks ())
11813 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
11815 ffecom_integer_type_node
11816 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11817 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11818 integer_zero_node);
11819 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11822 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11823 Turns out that by TYLONG, runtime/libI77/lio.h really means
11824 "whatever size an ftnint is". For consistency and sanity,
11825 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
11826 all are INTEGER, which we also make out of whatever back-end
11827 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
11828 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
11829 accommodate machines like the Alpha. Note that this suggests
11830 f2c and libf2c are missing a distinction perhaps needed on
11831 some machines between "int" and "long int". -- burley 0.5.5 950215 */
11833 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
11834 FFETARGET_f2cTYLONG);
11835 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
11836 FFETARGET_f2cTYSHORT);
11837 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
11838 FFETARGET_f2cTYINT1);
11839 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
11840 FFETARGET_f2cTYQUAD);
11841 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
11842 FFETARGET_f2cTYLOGICAL);
11843 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
11844 FFETARGET_f2cTYLOGICAL2);
11845 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
11846 FFETARGET_f2cTYLOGICAL1);
11847 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
11848 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
11849 FFETARGET_f2cTYQUAD);
11851 /* CHARACTER stuff is all special-cased, so it is not handled in the above
11852 loop. CHARACTER items are built as arrays of unsigned char. */
11854 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
11855 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
11856 type = ffetype_new ();
11858 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
11859 FFEINFO_kindtypeCHARACTER1,
11861 ffetype_set_ams (type,
11862 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11863 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11864 ffetype_set_kind (base_type, 1, type);
11865 assert (ffetype_size (type)
11866 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
11868 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
11869 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
11870 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
11871 [FFEINFO_kindtypeCHARACTER1]
11872 = ffecom_tree_ptr_to_fun_type_void;
11873 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
11874 = FFETARGET_f2cTYCHAR;
11876 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
11879 /* Make multi-return-value type and fields. */
11881 ffecom_multi_type_node_ = make_node (UNION_TYPE);
11885 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11886 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11890 if (ffecom_tree_type[i][j] == NULL_TREE)
11891 continue; /* Not supported. */
11892 sprintf (&name[0], "bt_%s_kt_%s",
11893 ffeinfo_basictype_string ((ffeinfoBasictype) i),
11894 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
11895 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
11896 get_identifier (name),
11897 ffecom_tree_type[i][j]);
11898 DECL_CONTEXT (ffecom_multi_fields_[i][j])
11899 = ffecom_multi_type_node_;
11900 DECL_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11901 DECL_USER_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11902 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
11903 field = ffecom_multi_fields_[i][j];
11906 TYPE_FIELDS (ffecom_multi_type_node_) = field;
11907 layout_type (ffecom_multi_type_node_);
11909 /* Subroutines usually return integer because they might have alternate
11912 ffecom_tree_subr_type
11913 = build_function_type (integer_type_node, NULL_TREE);
11914 ffecom_tree_ptr_to_subr_type
11915 = build_pointer_type (ffecom_tree_subr_type);
11916 ffecom_tree_blockdata_type
11917 = build_function_type (void_type_node, NULL_TREE);
11919 builtin_function ("__builtin_sqrtf", float_ftype_float,
11920 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtf");
11921 builtin_function ("__builtin_fsqrt", double_ftype_double,
11922 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrt");
11923 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
11924 BUILT_IN_FSQRT, BUILT_IN_NORMAL, "sqrtl");
11925 builtin_function ("__builtin_sinf", float_ftype_float,
11926 BUILT_IN_SIN, BUILT_IN_NORMAL, "sinf");
11927 builtin_function ("__builtin_sin", double_ftype_double,
11928 BUILT_IN_SIN, BUILT_IN_NORMAL, "sin");
11929 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
11930 BUILT_IN_SIN, BUILT_IN_NORMAL, "sinl");
11931 builtin_function ("__builtin_cosf", float_ftype_float,
11932 BUILT_IN_COS, BUILT_IN_NORMAL, "cosf");
11933 builtin_function ("__builtin_cos", double_ftype_double,
11934 BUILT_IN_COS, BUILT_IN_NORMAL, "cos");
11935 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
11936 BUILT_IN_COS, BUILT_IN_NORMAL, "cosl");
11939 pedantic_lvalues = FALSE;
11942 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
11945 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
11948 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
11951 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
11952 FFECOM_f2cDOUBLEREAL,
11954 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
11957 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
11958 FFECOM_f2cDOUBLECOMPLEX,
11960 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
11963 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
11966 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
11969 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
11972 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
11976 ffecom_f2c_ftnlen_zero_node
11977 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
11979 ffecom_f2c_ftnlen_one_node
11980 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
11982 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
11983 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
11985 ffecom_f2c_ptr_to_ftnlen_type_node
11986 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
11988 ffecom_f2c_ptr_to_ftnint_type_node
11989 = build_pointer_type (ffecom_f2c_ftnint_type_node);
11991 ffecom_f2c_ptr_to_integer_type_node
11992 = build_pointer_type (ffecom_f2c_integer_type_node);
11994 ffecom_f2c_ptr_to_real_type_node
11995 = build_pointer_type (ffecom_f2c_real_type_node);
11997 ffecom_float_zero_ = build_real (float_type_node, dconst0);
11998 ffecom_double_zero_ = build_real (double_type_node, dconst0);
12000 REAL_VALUE_TYPE point_5;
12002 #ifdef REAL_ARITHMETIC
12003 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
12007 ffecom_float_half_ = build_real (float_type_node, point_5);
12008 ffecom_double_half_ = build_real (double_type_node, point_5);
12011 /* Do "extern int xargc;". */
12013 ffecom_tree_xargc_ = build_decl (VAR_DECL,
12014 get_identifier ("f__xargc"),
12015 integer_type_node);
12016 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
12017 TREE_STATIC (ffecom_tree_xargc_) = 1;
12018 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
12019 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
12020 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
12022 #if 0 /* This is being fixed, and seems to be working now. */
12023 if ((FLOAT_TYPE_SIZE != 32)
12024 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
12026 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
12027 (int) FLOAT_TYPE_SIZE);
12028 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
12029 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
12030 warning ("properly unless they all are 32 bits wide.");
12031 warning ("Please keep this in mind before you report bugs. g77 should");
12032 warning ("support non-32-bit machines better as of version 0.6.");
12036 #if 0 /* Code in ste.c that would crash has been commented out. */
12037 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
12038 < TYPE_PRECISION (string_type_node))
12039 /* I/O will probably crash. */
12040 warning ("configuration: char * holds %d bits, but ftnlen only %d",
12041 TYPE_PRECISION (string_type_node),
12042 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
12045 #if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
12046 if (TYPE_PRECISION (ffecom_integer_type_node)
12047 < TYPE_PRECISION (string_type_node))
12048 /* ASSIGN 10 TO I will crash. */
12049 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
12050 ASSIGN statement might fail",
12051 TYPE_PRECISION (string_type_node),
12052 TYPE_PRECISION (ffecom_integer_type_node));
12057 /* ffecom_init_2 -- Initialize
12059 ffecom_init_2(); */
12061 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12065 assert (ffecom_outer_function_decl_ == NULL_TREE);
12066 assert (current_function_decl == NULL_TREE);
12067 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
12069 ffecom_master_arglist_ = NULL;
12071 ffecom_primary_entry_ = NULL;
12072 ffecom_is_altreturning_ = FALSE;
12073 ffecom_func_result_ = NULL_TREE;
12074 ffecom_multi_retval_ = NULL_TREE;
12078 /* ffecom_list_expr -- Transform list of exprs into gcc tree
12081 ffebld expr; // FFE opITEM list.
12082 tree = ffecom_list_expr(expr);
12084 List of actual args is transformed into corresponding gcc backend list. */
12086 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12088 ffecom_list_expr (ffebld expr)
12091 tree *plist = &list;
12092 tree trail = NULL_TREE; /* Append char length args here. */
12093 tree *ptrail = &trail;
12096 while (expr != NULL)
12098 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
12100 if (texpr == error_mark_node)
12101 return error_mark_node;
12103 *plist = build_tree_list (NULL_TREE, texpr);
12104 plist = &TREE_CHAIN (*plist);
12105 expr = ffebld_trail (expr);
12106 if (length != NULL_TREE)
12108 *ptrail = build_tree_list (NULL_TREE, length);
12109 ptrail = &TREE_CHAIN (*ptrail);
12119 /* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
12122 ffebld expr; // FFE opITEM list.
12123 tree = ffecom_list_ptr_to_expr(expr);
12125 List of actual args is transformed into corresponding gcc backend list for
12126 use in calling an external procedure (vs. a statement function). */
12128 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12130 ffecom_list_ptr_to_expr (ffebld expr)
12133 tree *plist = &list;
12134 tree trail = NULL_TREE; /* Append char length args here. */
12135 tree *ptrail = &trail;
12138 while (expr != NULL)
12140 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
12142 if (texpr == error_mark_node)
12143 return error_mark_node;
12145 *plist = build_tree_list (NULL_TREE, texpr);
12146 plist = &TREE_CHAIN (*plist);
12147 expr = ffebld_trail (expr);
12148 if (length != NULL_TREE)
12150 *ptrail = build_tree_list (NULL_TREE, length);
12151 ptrail = &TREE_CHAIN (*ptrail);
12161 /* Obtain gcc's LABEL_DECL tree for label. */
12163 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12165 ffecom_lookup_label (ffelab label)
12169 if (ffelab_hook (label) == NULL_TREE)
12171 char labelname[16];
12173 switch (ffelab_type (label))
12175 case FFELAB_typeLOOPEND:
12176 case FFELAB_typeNOTLOOP:
12177 case FFELAB_typeENDIF:
12178 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
12179 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
12181 DECL_CONTEXT (glabel) = current_function_decl;
12182 DECL_MODE (glabel) = VOIDmode;
12185 case FFELAB_typeFORMAT:
12186 glabel = build_decl (VAR_DECL,
12187 ffecom_get_invented_identifier
12188 ("__g77_format_%d", (int) ffelab_value (label)),
12189 build_type_variant (build_array_type
12193 TREE_CONSTANT (glabel) = 1;
12194 TREE_STATIC (glabel) = 1;
12195 DECL_CONTEXT (glabel) = current_function_decl;
12196 DECL_INITIAL (glabel) = NULL;
12197 make_decl_rtl (glabel, NULL);
12198 expand_decl (glabel);
12200 ffecom_save_tree_forever (glabel);
12204 case FFELAB_typeANY:
12205 glabel = error_mark_node;
12209 assert ("bad label type" == NULL);
12213 ffelab_set_hook (label, glabel);
12217 glabel = ffelab_hook (label);
12224 /* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12225 a single source specification (as in the fourth argument of MVBITS).
12226 If the type is NULL_TREE, the type of lhs is used to make the type of
12227 the MODIFY_EXPR. */
12229 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12231 ffecom_modify (tree newtype, tree lhs,
12234 if (lhs == error_mark_node || rhs == error_mark_node)
12235 return error_mark_node;
12237 if (newtype == NULL_TREE)
12238 newtype = TREE_TYPE (lhs);
12240 if (TREE_SIDE_EFFECTS (lhs))
12241 lhs = stabilize_reference (lhs);
12243 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12248 /* Register source file name. */
12251 ffecom_file (const char *name)
12253 #if FFECOM_GCC_INCLUDE
12254 ffecom_file_ (name);
12258 /* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
12261 ffecom_notify_init_storage(st);
12263 Gets called when all possible units in an aggregate storage area (a LOCAL
12264 with equivalences or a COMMON) have been initialized. The initialization
12265 info either is in ffestorag_init or, if that is NULL,
12266 ffestorag_accretion:
12268 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12269 even for an array if the array is one element in length!
12271 ffestorag_accretion will contain an opACCTER. It is much like an
12272 opARRTER except it has an ffebit object in it instead of just a size.
12273 The back end can use the info in the ffebit object, if it wants, to
12274 reduce the amount of actual initialization, but in any case it should
12275 kill the ffebit object when done. Also, set accretion to NULL but
12276 init to a non-NULL value.
12278 After performing initialization, DO NOT set init to NULL, because that'll
12279 tell the front end it is ok for more initialization to happen. Instead,
12280 set init to an opANY expression or some such thing that you can use to
12281 tell that you've already initialized the object.
12284 Support two-pass FFE. */
12287 ffecom_notify_init_storage (ffestorag st)
12289 ffebld init; /* The initialization expression. */
12290 #if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12291 ffetargetOffset size; /* The size of the entity. */
12292 ffetargetAlign pad; /* Its initial padding. */
12295 if (ffestorag_init (st) == NULL)
12297 init = ffestorag_accretion (st);
12298 assert (init != NULL);
12299 ffestorag_set_accretion (st, NULL);
12300 ffestorag_set_accretes (st, 0);
12302 #if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12303 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12304 size = ffebld_accter_size (init);
12305 pad = ffebld_accter_pad (init);
12306 ffebit_kill (ffebld_accter_bits (init));
12307 ffebld_set_op (init, FFEBLD_opARRTER);
12308 ffebld_set_arrter (init, ffebld_accter (init));
12309 ffebld_arrter_set_size (init, size);
12310 ffebld_arrter_set_pad (init, size);
12314 ffestorag_set_init (st, init);
12319 init = ffestorag_init (st);
12322 #if FFECOM_ONEPASS /* Process the inits, wipe 'em out. */
12323 ffestorag_set_init (st, ffebld_new_any ());
12325 if (ffebld_op (init) == FFEBLD_opANY)
12326 return; /* Oh, we already did this! */
12328 #if FFECOM_targetCURRENT == FFECOM_targetFFE
12332 if (ffestorag_symbol (st) != NULL)
12333 s = ffestorag_symbol (st);
12335 s = ffestorag_typesymbol (st);
12337 fprintf (dmpout, "= initialize_storage \"%s\" ",
12338 (s != NULL) ? ffesymbol_text (s) : "(unnamed)");
12339 ffebld_dump (init);
12340 fputc ('\n', dmpout);
12344 #endif /* if FFECOM_ONEPASS */
12347 /* ffecom_notify_init_symbol -- A symbol is now fully init'ed
12350 ffecom_notify_init_symbol(s);
12352 Gets called when all possible units in a symbol (not placed in COMMON
12353 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12354 have been initialized. The initialization info either is in
12355 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
12357 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12358 even for an array if the array is one element in length!
12360 ffesymbol_accretion will contain an opACCTER. It is much like an
12361 opARRTER except it has an ffebit object in it instead of just a size.
12362 The back end can use the info in the ffebit object, if it wants, to
12363 reduce the amount of actual initialization, but in any case it should
12364 kill the ffebit object when done. Also, set accretion to NULL but
12365 init to a non-NULL value.
12367 After performing initialization, DO NOT set init to NULL, because that'll
12368 tell the front end it is ok for more initialization to happen. Instead,
12369 set init to an opANY expression or some such thing that you can use to
12370 tell that you've already initialized the object.
12373 Support two-pass FFE. */
12376 ffecom_notify_init_symbol (ffesymbol s)
12378 ffebld init; /* The initialization expression. */
12379 #if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12380 ffetargetOffset size; /* The size of the entity. */
12381 ffetargetAlign pad; /* Its initial padding. */
12384 if (ffesymbol_storage (s) == NULL)
12385 return; /* Do nothing until COMMON/EQUIVALENCE
12386 possibilities checked. */
12388 if ((ffesymbol_init (s) == NULL)
12389 && ((init = ffesymbol_accretion (s)) != NULL))
12391 ffesymbol_set_accretion (s, NULL);
12392 ffesymbol_set_accretes (s, 0);
12394 #if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC
12395 /* For GNU backend, just turn ACCTER into ARRTER and proceed. */
12396 size = ffebld_accter_size (init);
12397 pad = ffebld_accter_pad (init);
12398 ffebit_kill (ffebld_accter_bits (init));
12399 ffebld_set_op (init, FFEBLD_opARRTER);
12400 ffebld_set_arrter (init, ffebld_accter (init));
12401 ffebld_arrter_set_size (init, size);
12402 ffebld_arrter_set_pad (init, size);
12406 ffesymbol_set_init (s, init);
12411 init = ffesymbol_init (s);
12415 ffesymbol_set_init (s, ffebld_new_any ());
12417 if (ffebld_op (init) == FFEBLD_opANY)
12418 return; /* Oh, we already did this! */
12420 #if FFECOM_targetCURRENT == FFECOM_targetFFE
12421 fprintf (dmpout, "= initialize_symbol \"%s\" ", ffesymbol_text (s));
12422 ffebld_dump (init);
12423 fputc ('\n', dmpout);
12426 #endif /* if FFECOM_ONEPASS */
12429 /* ffecom_notify_primary_entry -- Learn which is the primary entry point
12432 ffecom_notify_primary_entry(s);
12434 Gets called when implicit or explicit PROGRAM statement seen or when
12435 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12436 global symbol that serves as the entry point. */
12439 ffecom_notify_primary_entry (ffesymbol s)
12441 ffecom_primary_entry_ = s;
12442 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
12444 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12445 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12446 ffecom_primary_entry_is_proc_ = TRUE;
12448 ffecom_primary_entry_is_proc_ = FALSE;
12450 if (!ffe_is_silent ())
12452 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12453 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12455 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12458 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12459 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12464 for (list = ffesymbol_dummyargs (s);
12466 list = ffebld_trail (list))
12468 arg = ffebld_head (list);
12469 if (ffebld_op (arg) == FFEBLD_opSTAR)
12471 ffecom_is_altreturning_ = TRUE;
12480 ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12482 #if FFECOM_GCC_INCLUDE
12483 return ffecom_open_include_ (name, l, c);
12485 return fopen (name, "r");
12489 /* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
12492 ffebld expr; // FFE expression.
12493 tree = ffecom_ptr_to_expr(expr);
12495 Like ffecom_expr, but sticks address-of in front of most things. */
12497 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12499 ffecom_ptr_to_expr (ffebld expr)
12502 ffeinfoBasictype bt;
12503 ffeinfoKindtype kt;
12506 assert (expr != NULL);
12508 switch (ffebld_op (expr))
12510 case FFEBLD_opSYMTER:
12511 s = ffebld_symter (expr);
12512 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12516 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12517 assert (ix != FFECOM_gfrt);
12518 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12520 ffecom_make_gfrt_ (ix);
12521 item = ffecom_gfrt_[ix];
12526 item = ffesymbol_hook (s).decl_tree;
12527 if (item == NULL_TREE)
12529 s = ffecom_sym_transform_ (s);
12530 item = ffesymbol_hook (s).decl_tree;
12533 assert (item != NULL);
12534 if (item == error_mark_node)
12536 if (!ffesymbol_hook (s).addr)
12537 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12541 case FFEBLD_opARRAYREF:
12542 return ffecom_arrayref_ (NULL_TREE, expr, 1);
12544 case FFEBLD_opCONTER:
12546 bt = ffeinfo_basictype (ffebld_info (expr));
12547 kt = ffeinfo_kindtype (ffebld_info (expr));
12549 item = ffecom_constantunion (&ffebld_constant_union
12550 (ffebld_conter (expr)), bt, kt,
12551 ffecom_tree_type[bt][kt]);
12552 if (item == error_mark_node)
12553 return error_mark_node;
12554 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12559 return error_mark_node;
12562 bt = ffeinfo_basictype (ffebld_info (expr));
12563 kt = ffeinfo_kindtype (ffebld_info (expr));
12565 item = ffecom_expr (expr);
12566 if (item == error_mark_node)
12567 return error_mark_node;
12569 /* The back end currently optimizes a bit too zealously for us, in that
12570 we fail JCB001 if the following block of code is omitted. It checks
12571 to see if the transformed expression is a symbol or array reference,
12572 and encloses it in a SAVE_EXPR if that is the case. */
12575 if ((TREE_CODE (item) == VAR_DECL)
12576 || (TREE_CODE (item) == PARM_DECL)
12577 || (TREE_CODE (item) == RESULT_DECL)
12578 || (TREE_CODE (item) == INDIRECT_REF)
12579 || (TREE_CODE (item) == ARRAY_REF)
12580 || (TREE_CODE (item) == COMPONENT_REF)
12582 || (TREE_CODE (item) == OFFSET_REF)
12584 || (TREE_CODE (item) == BUFFER_REF)
12585 || (TREE_CODE (item) == REALPART_EXPR)
12586 || (TREE_CODE (item) == IMAGPART_EXPR))
12588 item = ffecom_save_tree (item);
12591 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12596 assert ("fall-through error" == NULL);
12597 return error_mark_node;
12601 /* Obtain a temp var with given data type.
12603 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12604 or >= 0 for a CHARACTER type.
12606 elements is -1 for a scalar or > 0 for an array of type. */
12608 #if FFECOM_targetCURRENT == FFECOM_targetGCC
12610 ffecom_make_tempvar (const char *commentary, tree type,
12611 ffetargetCharacterSize size, int elements)
12614 static int mynumber;
12616 assert (current_binding_level->prep_state < 2);
12618 if (type == error_mark_node)
12619 return error_mark_node;
12621 if (size != FFETARGET_charactersizeNONE)
12622 type = build_array_type (type,
12623 build_range_type (ffecom_f2c_ftnlen_type_node,
12624 ffecom_f2c_ftnlen_one_node,
12625 build_int_2 (size, 0)));
12626 if (elements != -1)
12627 type = build_array_type (type,
12628 build_range_type (integer_type_node,
12630 build_int_2 (elements - 1,
12632 t = build_decl (VAR_DECL,
12633 ffecom_get_invented_identifier ("__g77_%s_%d",
12638 t = start_decl (t, FALSE);
12639 finish_decl (t, NULL_TREE, FALSE);
12645 /* Prepare argument pointer to expression.
12647 Like ffecom_prepare_expr, except for expressions to be evaluated
12648 via ffecom_arg_ptr_to_expr. */
12651 ffecom_prepare_arg_ptr_to_expr (ffebld expr)
12653 /* ~~For now, it seems to be the same thing. */
12654 ffecom_prepare_expr (expr);
12658 /* End of preparations. */
12661 ffecom_prepare_end (void)
12663 int prep_state = current_binding_level->prep_state;
12665 assert (prep_state < 2);
12666 current_binding_level->prep_state = 2;
12668 return (prep_state == 1) ? TRUE : FALSE;
12671 /* Prepare expression.
12673 This is called before any code is generated for the current block.
12674 It scans the expression, declares any temporaries that might be needed
12675 during evaluation of the expression, and stores those temporaries in
12676 the appropriate "hook" fields of the expression. `dest', if not NULL,
12677 specifies the destination that ffecom_expr_ will see, in case that
12678 helps avoid generating unused temporaries.
12680 ~~Improve to avoid allocating unused temporaries by taking `dest'
12681 into account vis-a-vis aliasing requirements of complex/character
12685 ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
12687 ffeinfoBasictype bt;
12688 ffeinfoKindtype kt;
12689 ffetargetCharacterSize sz;
12690 tree tempvar = NULL_TREE;
12692 assert (current_binding_level->prep_state < 2);
12697 bt = ffeinfo_basictype (ffebld_info (expr));
12698 kt = ffeinfo_kindtype (ffebld_info (expr));
12699 sz = ffeinfo_size (ffebld_info (expr));
12701 /* Generate whatever temporaries are needed to represent the result
12702 of the expression. */
12704 if (bt == FFEINFO_basictypeCHARACTER)
12706 while (ffebld_op (expr) == FFEBLD_opPAREN)
12707 expr = ffebld_left (expr);
12710 switch (ffebld_op (expr))
12713 /* Don't make temps for SYMTER, CONTER, etc. */
12714 if (ffebld_arity (expr) == 0)
12719 case FFEINFO_basictypeCOMPLEX:
12720 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12724 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12727 s = ffebld_symter (ffebld_left (expr));
12728 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
12729 || (ffesymbol_where (s) != FFEINFO_whereINTRINSIC
12730 && ! ffesymbol_is_f2c (s))
12731 || (ffesymbol_where (s) == FFEINFO_whereINTRINSIC
12732 && ! ffe_is_f2c_library ()))
12735 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12737 /* Requires special treatment. There's no POW_CC function
12738 in libg2c, so POW_ZZ is used, which means we always
12739 need a double-complex temp, not a single-complex. */
12740 kt = FFEINFO_kindtypeREAL2;
12742 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12743 /* The other ops don't need temps for complex operands. */
12746 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12747 REAL(C). See 19990325-0.f, routine `check', for cases. */
12748 tempvar = ffecom_make_tempvar ("complex",
12750 [FFEINFO_basictypeCOMPLEX][kt],
12751 FFETARGET_charactersizeNONE,
12755 case FFEINFO_basictypeCHARACTER:
12756 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12759 if (sz == FFETARGET_charactersizeNONE)
12760 /* ~~Kludge alert! This should someday be fixed. */
12763 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
12772 case FFEBLD_opPOWER:
12775 tree rtmp, ltmp, result;
12777 ltype = ffecom_type_expr (ffebld_left (expr));
12778 rtype = ffecom_type_expr (ffebld_right (expr));
12780 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
12781 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12782 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12784 tempvar = make_tree_vec (3);
12785 TREE_VEC_ELT (tempvar, 0) = rtmp;
12786 TREE_VEC_ELT (tempvar, 1) = ltmp;
12787 TREE_VEC_ELT (tempvar, 2) = result;
12792 case FFEBLD_opCONCATENATE:
12794 /* This gets special handling, because only one set of temps
12795 is needed for a tree of these -- the tree is treated as
12796 a flattened list of concatenations when generating code. */
12798 ffecomConcatList_ catlist;
12799 tree ltmp, itmp, result;
12803 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12804 count = ffecom_concat_list_count_ (catlist);
12809 = ffecom_make_tempvar ("concat_len",
12810 ffecom_f2c_ftnlen_type_node,
12811 FFETARGET_charactersizeNONE, count);
12813 = ffecom_make_tempvar ("concat_item",
12814 ffecom_f2c_address_type_node,
12815 FFETARGET_charactersizeNONE, count);
12817 = ffecom_make_tempvar ("concat_res",
12819 ffecom_concat_list_maxlen_ (catlist),
12822 tempvar = make_tree_vec (3);
12823 TREE_VEC_ELT (tempvar, 0) = ltmp;
12824 TREE_VEC_ELT (tempvar, 1) = itmp;
12825 TREE_VEC_ELT (tempvar, 2) = result;
12828 for (i = 0; i < count; ++i)
12829 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
12832 ffecom_concat_list_kill_ (catlist);
12836 ffebld_nonter_set_hook (expr, tempvar);
12837 current_binding_level->prep_state = 1;
12842 case FFEBLD_opCONVERT:
12843 if (bt == FFEINFO_basictypeCHARACTER
12844 && ((ffebld_size_known (ffebld_left (expr))
12845 == FFETARGET_charactersizeNONE)
12846 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
12847 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
12853 ffebld_nonter_set_hook (expr, tempvar);
12854 current_binding_level->prep_state = 1;
12857 /* Prepare subexpressions for this expr. */
12859 switch (ffebld_op (expr))
12861 case FFEBLD_opPERCENT_LOC:
12862 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
12865 case FFEBLD_opPERCENT_VAL:
12866 case FFEBLD_opPERCENT_REF:
12867 ffecom_prepare_expr (ffebld_left (expr));
12870 case FFEBLD_opPERCENT_DESCR:
12871 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
12874 case FFEBLD_opITEM:
12880 item = ffebld_trail (item))
12881 if (ffebld_head (item) != NULL)
12882 ffecom_prepare_expr (ffebld_head (item));
12887 /* Need to handle character conversion specially. */
12888 switch (ffebld_arity (expr))
12891 ffecom_prepare_expr (ffebld_left (expr));
12892 ffecom_prepare_expr (ffebld_right (expr));
12896 ffecom_prepare_expr (ffebld_left (expr));
12907 /* Prepare expression for reading and writing.
12909 Like ffecom_prepare_expr, except for expressions to be evaluated
12910 via ffecom_expr_rw. */
12913 ffecom_prepare_expr_rw (tree type, ffebld expr)
12915 /* This is all we support for now. */
12916 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
12918 /* ~~For now, it seems to be the same thing. */
12919 ffecom_prepare_expr (expr);
12923 /* Prepare expression for writing.
12925 Like ffecom_prepare_expr, except for expressions to be evaluated
12926 via ffecom_expr_w. */
12929 ffecom_prepare_expr_w (tree type, ffebld expr)
12931 /* This is all we support for now. */
12932 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
12934 /* ~~For now, it seems to be the same thing. */
12935 ffecom_prepare_expr (expr);
12939 /* Prepare expression for returning.
12941 Like ffecom_prepare_expr, except for expressions to be evaluated
12942 via ffecom_return_expr. */
12945 ffecom_prepare_return_expr (ffebld expr)
12947 assert (current_binding_level->prep_state < 2);
12949 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
12950 && ffecom_is_altreturning_
12952 ffecom_prepare_expr (expr);
12955 /* Prepare pointer to expression.
12957 Like ffecom_prepare_expr, except for expressions to be evaluated
12958 via ffecom_ptr_to_expr. */
12961 ffecom_prepare_ptr_to_expr (ffebld expr)
12963 /* ~~For now, it seems to be the same thing. */
12964 ffecom_prepare_expr (expr);
12968 /* Transform expression into constant pointer-to-expression tree.
12970 If the expression can be transformed into a pointer-to-expression tree
12971 that is constant, that is done, and the tree returned. Else NULL_TREE
12974 That way, a caller can attempt to provide compile-time initialization
12975 of a variable and, if that fails, *then* choose to start a new block
12976 and resort to using temporaries, as appropriate. */
12979 ffecom_ptr_to_const_expr (ffebld expr)
12982 return integer_zero_node;
12984 if (ffebld_op (expr) == FFEBLD_opANY)
12985 return error_mark_node;
12987 if (ffebld_arity (expr) == 0
12988 && (ffebld_op (expr) != FFEBLD_opSYMTER
12989 || ffebld_where (expr) == FFEINFO_whereCOMMON
12990 || ffebld_where (expr) == FFEINFO_whereGLOBAL
12991 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
12995 t = ffecom_ptr_to_expr (expr);
12996 assert (TREE_CONSTANT (t));
13003 /* ffecom_return_expr -- Returns return-value expr given alt return expr
13005 tree rtn; // NULL_TREE means use expand_null_return()
13006 ffebld expr; // NULL if no alt return expr to RETURN stmt
13007 rtn = ffecom_return_expr(expr);
13009 Based on the program unit type and other info (like return function
13010 type, return master function type when alternate ENTRY points,
13011 whether subroutine has any alternate RETURN points, etc), returns the
13012 appropriate expression to be returned to the caller, or NULL_TREE
13013 meaning no return value or the caller expects it to be returned somewhere
13014 else (which is handled by other parts of this module). */
13016 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13018 ffecom_return_expr (ffebld expr)
13022 switch (ffecom_primary_entry_kind_)
13024 case FFEINFO_kindPROGRAM:
13025 case FFEINFO_kindBLOCKDATA:
13029 case FFEINFO_kindSUBROUTINE:
13030 if (!ffecom_is_altreturning_)
13031 rtn = NULL_TREE; /* No alt returns, never an expr. */
13032 else if (expr == NULL)
13033 rtn = integer_zero_node;
13035 rtn = ffecom_expr (expr);
13038 case FFEINFO_kindFUNCTION:
13039 if ((ffecom_multi_retval_ != NULL_TREE)
13040 || (ffesymbol_basictype (ffecom_primary_entry_)
13041 == FFEINFO_basictypeCHARACTER)
13042 || ((ffesymbol_basictype (ffecom_primary_entry_)
13043 == FFEINFO_basictypeCOMPLEX)
13044 && (ffecom_num_entrypoints_ == 0)
13045 && ffesymbol_is_f2c (ffecom_primary_entry_)))
13046 { /* Value is returned by direct assignment
13047 into (implicit) dummy. */
13051 rtn = ffecom_func_result_;
13053 /* Spurious error if RETURN happens before first reference! So elide
13054 this code. In particular, for debugging registry, rtn should always
13055 be non-null after all, but TREE_USED won't be set until we encounter
13056 a reference in the code. Perfectly okay (but weird) code that,
13057 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
13058 this diagnostic for no reason. Have people use -O -Wuninitialized
13059 and leave it to the back end to find obviously weird cases. */
13061 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
13062 situation; if the return value has never been referenced, it won't
13063 have a tree under 2pass mode. */
13064 if ((rtn == NULL_TREE)
13065 || !TREE_USED (rtn))
13067 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
13068 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
13069 ffesymbol_where_column (ffecom_primary_entry_));
13070 ffebad_string (ffesymbol_text (ffesymbol_funcresult
13071 (ffecom_primary_entry_)));
13078 assert ("bad unit kind" == NULL);
13079 case FFEINFO_kindANY:
13080 rtn = error_mark_node;
13088 /* Do save_expr only if tree is not error_mark_node. */
13090 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13092 ffecom_save_tree (tree t)
13094 return save_expr (t);
13098 /* Start a compound statement (block). */
13100 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13102 ffecom_start_compstmt (void)
13104 bison_rule_pushlevel_ ();
13106 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
13108 /* Public entry point for front end to access start_decl. */
13110 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13112 ffecom_start_decl (tree decl, bool is_initialized)
13114 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
13115 return start_decl (decl, FALSE);
13119 /* ffecom_sym_commit -- Symbol's state being committed to reality
13122 ffecom_sym_commit(s);
13124 Does whatever the backend needs when a symbol is committed after having
13125 been backtrackable for a period of time. */
13127 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13129 ffecom_sym_commit (ffesymbol s UNUSED)
13131 assert (!ffesymbol_retractable ());
13135 /* ffecom_sym_end_transition -- Perform end transition on all symbols
13137 ffecom_sym_end_transition();
13139 Does backend-specific stuff and also calls ffest_sym_end_transition
13140 to do the necessary FFE stuff.
13142 Backtracking is never enabled when this fn is called, so don't worry
13146 ffecom_sym_end_transition (ffesymbol s)
13150 assert (!ffesymbol_retractable ());
13152 s = ffest_sym_end_transition (s);
13154 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13155 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
13156 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
13158 ffecom_list_blockdata_
13159 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13160 FFEINTRIN_specNONE,
13161 FFEINTRIN_impNONE),
13162 ffecom_list_blockdata_);
13166 /* This is where we finally notice that a symbol has partial initialization
13167 and finalize it. */
13169 if (ffesymbol_accretion (s) != NULL)
13171 assert (ffesymbol_init (s) == NULL);
13172 ffecom_notify_init_symbol (s);
13174 else if (((st = ffesymbol_storage (s)) != NULL)
13175 && ((st = ffestorag_parent (st)) != NULL)
13176 && (ffestorag_accretion (st) != NULL))
13178 assert (ffestorag_init (st) == NULL);
13179 ffecom_notify_init_storage (st);
13182 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13183 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
13184 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
13185 && (ffesymbol_storage (s) != NULL))
13187 ffecom_list_common_
13188 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
13189 FFEINTRIN_specNONE,
13190 FFEINTRIN_impNONE),
13191 ffecom_list_common_);
13198 /* ffecom_sym_exec_transition -- Perform exec transition on all symbols
13200 ffecom_sym_exec_transition();
13202 Does backend-specific stuff and also calls ffest_sym_exec_transition
13203 to do the necessary FFE stuff.
13205 See the long-winded description in ffecom_sym_learned for info
13206 on handling the situation where backtracking is inhibited. */
13209 ffecom_sym_exec_transition (ffesymbol s)
13211 s = ffest_sym_exec_transition (s);
13216 /* ffecom_sym_learned -- Initial or more info gained on symbol after exec
13219 s = ffecom_sym_learned(s);
13221 Called when a new symbol is seen after the exec transition or when more
13222 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
13223 it arrives here is that all its latest info is updated already, so its
13224 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
13225 field filled in if its gone through here or exec_transition first, and
13228 The backend probably wants to check ffesymbol_retractable() to see if
13229 backtracking is in effect. If so, the FFE's changes to the symbol may
13230 be retracted (undone) or committed (ratified), at which time the
13231 appropriate ffecom_sym_retract or _commit function will be called
13234 If the backend has its own backtracking mechanism, great, use it so that
13235 committal is a simple operation. Though it doesn't make much difference,
13236 I suppose: the reason for tentative symbol evolution in the FFE is to
13237 enable error detection in weird incorrect statements early and to disable
13238 incorrect error detection on a correct statement. The backend is not
13239 likely to introduce any information that'll get involved in these
13240 considerations, so it is probably just fine that the implementation
13241 model for this fn and for _exec_transition is to not do anything
13242 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
13243 and instead wait until ffecom_sym_commit is called (which it never
13244 will be as long as we're using ambiguity-detecting statement analysis in
13245 the FFE, which we are initially to shake out the code, but don't depend
13246 on this), otherwise go ahead and do whatever is needed.
13248 In essence, then, when this fn and _exec_transition get called while
13249 backtracking is enabled, a general mechanism would be to flag which (or
13250 both) of these were called (and in what order? neat question as to what
13251 might happen that I'm too lame to think through right now) and then when
13252 _commit is called reproduce the original calling sequence, if any, for
13253 the two fns (at which point backtracking will, of course, be disabled). */
13256 ffecom_sym_learned (ffesymbol s)
13258 ffestorag_exec_layout (s);
13263 /* ffecom_sym_retract -- Symbol's state being retracted from reality
13266 ffecom_sym_retract(s);
13268 Does whatever the backend needs when a symbol is retracted after having
13269 been backtrackable for a period of time. */
13271 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13273 ffecom_sym_retract (ffesymbol s UNUSED)
13275 assert (!ffesymbol_retractable ());
13277 #if 0 /* GCC doesn't commit any backtrackable sins,
13278 so nothing needed here. */
13279 switch (ffesymbol_hook (s).state)
13281 case 0: /* nothing happened yet. */
13284 case 1: /* exec transition happened. */
13287 case 2: /* learned happened. */
13290 case 3: /* learned then exec. */
13293 case 4: /* exec then learned. */
13297 assert ("bad hook state" == NULL);
13304 /* Create temporary gcc label. */
13306 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13308 ffecom_temp_label ()
13311 static int mynumber = 0;
13313 glabel = build_decl (LABEL_DECL,
13314 ffecom_get_invented_identifier ("__g77_label_%d",
13317 DECL_CONTEXT (glabel) = current_function_decl;
13318 DECL_MODE (glabel) = VOIDmode;
13324 /* Return an expression that is usable as an arg in a conditional context
13325 (IF, DO WHILE, .NOT., and so on).
13327 Use the one provided for the back end as of >2.6.0. */
13329 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13331 ffecom_truth_value (tree expr)
13333 return truthvalue_conversion (expr);
13337 /* Return the inversion of a truth value (the inversion of what
13338 ffecom_truth_value builds).
13340 Apparently invert_truthvalue, which is properly in the back end, is
13341 enough for now, so just use it. */
13343 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13345 ffecom_truth_value_invert (tree expr)
13347 return invert_truthvalue (ffecom_truth_value (expr));
13352 /* Return the tree that is the type of the expression, as would be
13353 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13354 transforming the expression, generating temporaries, etc. */
13357 ffecom_type_expr (ffebld expr)
13359 ffeinfoBasictype bt;
13360 ffeinfoKindtype kt;
13363 assert (expr != NULL);
13365 bt = ffeinfo_basictype (ffebld_info (expr));
13366 kt = ffeinfo_kindtype (ffebld_info (expr));
13367 tree_type = ffecom_tree_type[bt][kt];
13369 switch (ffebld_op (expr))
13371 case FFEBLD_opCONTER:
13372 case FFEBLD_opSYMTER:
13373 case FFEBLD_opARRAYREF:
13374 case FFEBLD_opUPLUS:
13375 case FFEBLD_opPAREN:
13376 case FFEBLD_opUMINUS:
13378 case FFEBLD_opSUBTRACT:
13379 case FFEBLD_opMULTIPLY:
13380 case FFEBLD_opDIVIDE:
13381 case FFEBLD_opPOWER:
13383 case FFEBLD_opFUNCREF:
13384 case FFEBLD_opSUBRREF:
13388 case FFEBLD_opNEQV:
13390 case FFEBLD_opCONVERT:
13397 case FFEBLD_opPERCENT_LOC:
13400 case FFEBLD_opACCTER:
13401 case FFEBLD_opARRTER:
13402 case FFEBLD_opITEM:
13403 case FFEBLD_opSTAR:
13404 case FFEBLD_opBOUNDS:
13405 case FFEBLD_opREPEAT:
13406 case FFEBLD_opLABTER:
13407 case FFEBLD_opLABTOK:
13408 case FFEBLD_opIMPDO:
13409 case FFEBLD_opCONCATENATE:
13410 case FFEBLD_opSUBSTR:
13412 assert ("bad op for ffecom_type_expr" == NULL);
13413 /* Fall through. */
13415 return error_mark_node;
13419 /* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13421 If the PARM_DECL already exists, return it, else create it. It's an
13422 integer_type_node argument for the master function that implements a
13423 subroutine or function with more than one entrypoint and is bound at
13424 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13425 first ENTRY statement, and so on). */
13427 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13429 ffecom_which_entrypoint_decl ()
13431 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13433 return ffecom_which_entrypoint_decl_;
13438 /* The following sections consists of private and public functions
13439 that have the same names and perform roughly the same functions
13440 as counterparts in the C front end. Changes in the C front end
13441 might affect how things should be done here. Only functions
13442 needed by the back end should be public here; the rest should
13443 be private (static in the C sense). Functions needed by other
13444 g77 front-end modules should be accessed by them via public
13445 ffecom_* names, which should themselves call private versions
13446 in this section so the private versions are easy to recognize
13447 when upgrading to a new gcc and finding interesting changes
13450 Functions named after rule "foo:" in c-parse.y are named
13451 "bison_rule_foo_" so they are easy to find. */
13453 #if FFECOM_targetCURRENT == FFECOM_targetGCC
13456 bison_rule_pushlevel_ ()
13458 emit_line_note (input_filename, lineno);
13460 clear_last_expr ();
13461 expand_start_bindings (0);
13465 bison_rule_compstmt_ ()
13468 int keep = kept_level_p ();
13470 /* Make the temps go away. */
13472 current_binding_level->names = NULL_TREE;
13474 emit_line_note (input_filename, lineno);
13475 expand_end_bindings (getdecls (), keep, 0);
13476 t = poplevel (keep, 1, 0);
13481 /* Return a definition for a builtin function named NAME and whose data type
13482 is TYPE. TYPE should be a function type with argument types.
13483 FUNCTION_CODE tells later passes how to compile calls to this function.
13484 See tree.h for its possible values.
13486 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13487 the name to be called if we can't opencode the function. */
13490 builtin_function (const char *name, tree type, int function_code,
13491 enum built_in_class class,
13492 const char *library_name)
13494 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13495 DECL_EXTERNAL (decl) = 1;
13496 TREE_PUBLIC (decl) = 1;
13498 SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
13499 make_decl_rtl (decl, NULL);
13501 DECL_BUILT_IN_CLASS (decl) = class;
13502 DECL_FUNCTION_CODE (decl) = function_code;
13507 /* Handle when a new declaration NEWDECL
13508 has the same name as an old one OLDDECL
13509 in the same binding contour.
13510 Prints an error message if appropriate.
13512 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13513 Otherwise, return 0. */
13516 duplicate_decls (tree newdecl, tree olddecl)
13518 int types_match = 1;
13519 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13520 && DECL_INITIAL (newdecl) != 0);
13521 tree oldtype = TREE_TYPE (olddecl);
13522 tree newtype = TREE_TYPE (newdecl);
13524 if (olddecl == newdecl)
13527 if (TREE_CODE (newtype) == ERROR_MARK
13528 || TREE_CODE (oldtype) == ERROR_MARK)
13531 /* New decl is completely inconsistent with the old one =>
13532 tell caller to replace the old one.
13533 This is always an error except in the case of shadowing a builtin. */
13534 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13537 /* For real parm decl following a forward decl,
13538 return 1 so old decl will be reused. */
13539 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13540 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13543 /* The new declaration is the same kind of object as the old one.
13544 The declarations may partially match. Print warnings if they don't
13545 match enough. Ultimately, copy most of the information from the new
13546 decl to the old one, and keep using the old one. */
13548 if (TREE_CODE (olddecl) == FUNCTION_DECL
13549 && DECL_BUILT_IN (olddecl))
13551 /* A function declaration for a built-in function. */
13552 if (!TREE_PUBLIC (newdecl))
13554 else if (!types_match)
13556 /* Accept the return type of the new declaration if same modes. */
13557 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13558 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
13560 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13562 /* Function types may be shared, so we can't just modify
13563 the return type of olddecl's function type. */
13565 = build_function_type (newreturntype,
13566 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
13570 TREE_TYPE (olddecl) = newtype;
13576 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13577 && DECL_SOURCE_LINE (olddecl) == 0)
13579 /* A function declaration for a predeclared function
13580 that isn't actually built in. */
13581 if (!TREE_PUBLIC (newdecl))
13583 else if (!types_match)
13585 /* If the types don't match, preserve volatility indication.
13586 Later on, we will discard everything else about the
13587 default declaration. */
13588 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13592 /* Copy all the DECL_... slots specified in the new decl
13593 except for any that we copy here from the old type.
13595 Past this point, we don't change OLDTYPE and NEWTYPE
13596 even if we change the types of NEWDECL and OLDDECL. */
13600 /* Merge the data types specified in the two decls. */
13601 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13602 TREE_TYPE (newdecl)
13603 = TREE_TYPE (olddecl)
13604 = TREE_TYPE (newdecl);
13606 /* Lay the type out, unless already done. */
13607 if (oldtype != TREE_TYPE (newdecl))
13609 if (TREE_TYPE (newdecl) != error_mark_node)
13610 layout_type (TREE_TYPE (newdecl));
13611 if (TREE_CODE (newdecl) != FUNCTION_DECL
13612 && TREE_CODE (newdecl) != TYPE_DECL
13613 && TREE_CODE (newdecl) != CONST_DECL)
13614 layout_decl (newdecl, 0);
13618 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13619 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
13620 DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
13621 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13622 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
13624 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13625 DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
13629 /* Keep the old rtl since we can safely use it. */
13630 COPY_DECL_RTL (olddecl, newdecl);
13632 /* Merge the type qualifiers. */
13633 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13634 && !TREE_THIS_VOLATILE (newdecl))
13635 TREE_THIS_VOLATILE (olddecl) = 0;
13636 if (TREE_READONLY (newdecl))
13637 TREE_READONLY (olddecl) = 1;
13638 if (TREE_THIS_VOLATILE (newdecl))
13640 TREE_THIS_VOLATILE (olddecl) = 1;
13641 if (TREE_CODE (newdecl) == VAR_DECL)
13642 make_var_volatile (newdecl);
13645 /* Keep source location of definition rather than declaration.
13646 Likewise, keep decl at outer scope. */
13647 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13648 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13650 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13651 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
13653 if (DECL_CONTEXT (olddecl) == 0
13654 && TREE_CODE (newdecl) != FUNCTION_DECL)
13655 DECL_CONTEXT (newdecl) = 0;
13658 /* Merge the unused-warning information. */
13659 if (DECL_IN_SYSTEM_HEADER (olddecl))
13660 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13661 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13662 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
13664 /* Merge the initialization information. */
13665 if (DECL_INITIAL (newdecl) == 0)
13666 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13668 /* Merge the section attribute.
13669 We want to issue an error if the sections conflict but that must be
13670 done later in decl_attributes since we are called before attributes
13672 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13673 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
13676 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13678 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13679 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13683 /* If cannot merge, then use the new type and qualifiers,
13684 and don't preserve the old rtl. */
13687 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13688 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13689 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13690 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13693 /* Merge the storage class information. */
13694 /* For functions, static overrides non-static. */
13695 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13697 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13698 /* This is since we don't automatically
13699 copy the attributes of NEWDECL into OLDDECL. */
13700 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13701 /* If this clears `static', clear it in the identifier too. */
13702 if (! TREE_PUBLIC (olddecl))
13703 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13705 if (DECL_EXTERNAL (newdecl))
13707 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13708 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13709 /* An extern decl does not override previous storage class. */
13710 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13714 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13715 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13718 /* If either decl says `inline', this fn is inline,
13719 unless its definition was passed already. */
13720 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13721 DECL_INLINE (olddecl) = 1;
13722 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
13724 /* Get rid of any built-in function if new arg types don't match it
13725 or if we have a function definition. */
13726 if (TREE_CODE (newdecl) == FUNCTION_DECL
13727 && DECL_BUILT_IN (olddecl)
13728 && (!types_match || new_is_definition))
13730 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13731 DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
13734 /* If redeclaring a builtin function, and not a definition,
13736 Also preserve various other info from the definition. */
13737 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13739 if (DECL_BUILT_IN (olddecl))
13741 DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
13742 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13745 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13746 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13747 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13748 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13751 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13752 But preserve olddecl's DECL_UID. */
13754 register unsigned olddecl_uid = DECL_UID (olddecl);
13756 memcpy ((char *) olddecl + sizeof (struct tree_common),
13757 (char *) newdecl + sizeof (struct tree_common),
13758 sizeof (struct tree_decl) - sizeof (struct tree_common));
13759 DECL_UID (olddecl) = olddecl_uid;
13765 /* Finish processing of a declaration;
13766 install its initial value.
13767 If the length of an array type is not known before,
13768 it must be determined now, from the initial value, or it is an error. */
13771 finish_decl (tree decl, tree init, bool is_top_level)
13773 register tree type = TREE_TYPE (decl);
13774 int was_incomplete = (DECL_SIZE (decl) == 0);
13775 bool at_top_level = (current_binding_level == global_binding_level);
13776 bool top_level = is_top_level || at_top_level;
13778 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13780 assert (!is_top_level || !at_top_level);
13782 if (TREE_CODE (decl) == PARM_DECL)
13783 assert (init == NULL_TREE);
13784 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
13785 overlaps DECL_ARG_TYPE. */
13786 else if (init == NULL_TREE)
13787 assert (DECL_INITIAL (decl) == NULL_TREE);
13789 assert (DECL_INITIAL (decl) == error_mark_node);
13791 if (init != NULL_TREE)
13793 if (TREE_CODE (decl) != TYPE_DECL)
13794 DECL_INITIAL (decl) = init;
13797 /* typedef foo = bar; store the type of bar as the type of foo. */
13798 TREE_TYPE (decl) = TREE_TYPE (init);
13799 DECL_INITIAL (decl) = init = 0;
13803 /* Deduce size of array from initialization, if not already known */
13805 if (TREE_CODE (type) == ARRAY_TYPE
13806 && TYPE_DOMAIN (type) == 0
13807 && TREE_CODE (decl) != TYPE_DECL)
13809 assert (top_level);
13810 assert (was_incomplete);
13812 layout_decl (decl, 0);
13815 if (TREE_CODE (decl) == VAR_DECL)
13817 if (DECL_SIZE (decl) == NULL_TREE
13818 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
13819 layout_decl (decl, 0);
13821 if (DECL_SIZE (decl) == NULL_TREE
13822 && (TREE_STATIC (decl)
13824 /* A static variable with an incomplete type is an error if it is
13825 initialized. Also if it is not file scope. Otherwise, let it
13826 through, but if it is not `extern' then it may cause an error
13828 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
13830 /* An automatic variable with an incomplete type is an error. */
13831 !DECL_EXTERNAL (decl)))
13833 assert ("storage size not known" == NULL);
13837 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
13838 && (DECL_SIZE (decl) != 0)
13839 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
13841 assert ("storage size not constant" == NULL);
13846 /* Output the assembler code and/or RTL code for variables and functions,
13847 unless the type is an undefined structure or union. If not, it will get
13848 done when the type is completed. */
13850 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
13852 rest_of_decl_compilation (decl, NULL,
13853 DECL_CONTEXT (decl) == 0,
13856 if (DECL_CONTEXT (decl) != 0)
13858 /* Recompute the RTL of a local array now if it used to be an
13859 incomplete type. */
13861 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
13863 /* If we used it already as memory, it must stay in memory. */
13864 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
13865 /* If it's still incomplete now, no init will save it. */
13866 if (DECL_SIZE (decl) == 0)
13867 DECL_INITIAL (decl) = 0;
13868 expand_decl (decl);
13870 /* Compute and store the initial value. */
13871 if (TREE_CODE (decl) != FUNCTION_DECL)
13872 expand_decl_init (decl);
13875 else if (TREE_CODE (decl) == TYPE_DECL)
13877 rest_of_decl_compilation (decl, NULL,
13878 DECL_CONTEXT (decl) == 0,
13882 /* At the end of a declaration, throw away any variable type sizes of types
13883 defined inside that declaration. There is no use computing them in the
13884 following function definition. */
13885 if (current_binding_level == global_binding_level)
13886 get_pending_sizes ();
13889 /* Finish up a function declaration and compile that function
13890 all the way to assembler language output. The free the storage
13891 for the function definition.
13893 This is called after parsing the body of the function definition.
13895 NESTED is nonzero if the function being finished is nested in another. */
13898 finish_function (int nested)
13900 register tree fndecl = current_function_decl;
13902 assert (fndecl != NULL_TREE);
13903 if (TREE_CODE (fndecl) != ERROR_MARK)
13906 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
13908 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
13911 /* TREE_READONLY (fndecl) = 1;
13912 This caused &foo to be of type ptr-to-const-function
13913 which then got a warning when stored in a ptr-to-function variable. */
13915 poplevel (1, 0, 1);
13917 if (TREE_CODE (fndecl) != ERROR_MARK)
13919 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
13921 /* Must mark the RESULT_DECL as being in this function. */
13923 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
13925 /* Obey `register' declarations if `setjmp' is called in this fn. */
13926 /* Generate rtl for function exit. */
13927 expand_function_end (input_filename, lineno, 0);
13929 /* If this is a nested function, protect the local variables in the stack
13930 above us from being collected while we're compiling this function. */
13932 ggc_push_context ();
13934 /* Run the optimizers and output the assembler code for this function. */
13935 rest_of_compilation (fndecl);
13937 /* Undo the GC context switch. */
13939 ggc_pop_context ();
13942 if (TREE_CODE (fndecl) != ERROR_MARK
13944 && DECL_SAVED_INSNS (fndecl) == 0)
13946 /* Stop pointing to the local nodes about to be freed. */
13947 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13948 function definition. */
13949 /* For a nested function, this is done in pop_f_function_context. */
13950 /* If rest_of_compilation set this to 0, leave it 0. */
13951 if (DECL_INITIAL (fndecl) != 0)
13952 DECL_INITIAL (fndecl) = error_mark_node;
13953 DECL_ARGUMENTS (fndecl) = 0;
13958 /* Let the error reporting routines know that we're outside a function.
13959 For a nested function, this value is used in pop_c_function_context
13960 and then reset via pop_function_context. */
13961 ffecom_outer_function_decl_ = current_function_decl = NULL;
13965 /* Plug-in replacement for identifying the name of a decl and, for a
13966 function, what we call it in diagnostics. For now, "program unit"
13967 should suffice, since it's a bit of a hassle to figure out which
13968 of several kinds of things it is. Note that it could conceivably
13969 be a statement function, which probably isn't really a program unit
13970 per se, but if that comes up, it should be easy to check (being a
13971 nested function and all). */
13973 static const char *
13974 lang_printable_name (tree decl, int v)
13976 /* Just to keep GCC quiet about the unused variable.
13977 In theory, differing values of V should produce different
13982 if (TREE_CODE (decl) == ERROR_MARK)
13983 return "erroneous code";
13984 return IDENTIFIER_POINTER (DECL_NAME (decl));
13988 /* g77's function to print out name of current function that caused
13993 lang_print_error_function (diagnostic_context *context __attribute__((unused)),
13996 static ffeglobal last_g = NULL;
13997 static ffesymbol last_s = NULL;
14002 if ((ffecom_primary_entry_ == NULL)
14003 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
14011 g = ffesymbol_global (ffecom_primary_entry_);
14012 if (ffecom_nested_entry_ == NULL)
14014 s = ffecom_primary_entry_;
14015 switch (ffesymbol_kind (s))
14017 case FFEINFO_kindFUNCTION:
14021 case FFEINFO_kindSUBROUTINE:
14022 kind = "subroutine";
14025 case FFEINFO_kindPROGRAM:
14029 case FFEINFO_kindBLOCKDATA:
14030 kind = "block-data";
14034 kind = ffeinfo_kind_message (ffesymbol_kind (s));
14040 s = ffecom_nested_entry_;
14041 kind = "statement function";
14045 if ((last_g != g) || (last_s != s))
14048 fprintf (stderr, "%s: ", file);
14051 fprintf (stderr, "Outside of any program unit:\n");
14054 const char *name = ffesymbol_text (s);
14056 fprintf (stderr, "In %s `%s':\n", kind, name);
14065 /* Similar to `lookup_name' but look only at current binding level. */
14068 lookup_name_current_level (tree name)
14072 if (current_binding_level == global_binding_level)
14073 return IDENTIFIER_GLOBAL_VALUE (name);
14075 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
14078 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
14079 if (DECL_NAME (t) == name)
14085 /* Create a new `struct binding_level'. */
14087 static struct binding_level *
14088 make_binding_level ()
14091 return (struct binding_level *) xmalloc (sizeof (struct binding_level));
14094 /* Save and restore the variables in this file and elsewhere
14095 that keep track of the progress of compilation of the current function.
14096 Used for nested functions. */
14100 struct f_function *next;
14102 tree shadowed_labels;
14103 struct binding_level *binding_level;
14106 struct f_function *f_function_chain;
14108 /* Restore the variables used during compilation of a C function. */
14111 pop_f_function_context ()
14113 struct f_function *p = f_function_chain;
14116 /* Bring back all the labels that were shadowed. */
14117 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
14118 if (DECL_NAME (TREE_VALUE (link)) != 0)
14119 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
14120 = TREE_VALUE (link);
14122 if (current_function_decl != error_mark_node
14123 && DECL_SAVED_INSNS (current_function_decl) == 0)
14125 /* Stop pointing to the local nodes about to be freed. */
14126 /* But DECL_INITIAL must remain nonzero so we know this was an actual
14127 function definition. */
14128 DECL_INITIAL (current_function_decl) = error_mark_node;
14129 DECL_ARGUMENTS (current_function_decl) = 0;
14132 pop_function_context ();
14134 f_function_chain = p->next;
14136 named_labels = p->named_labels;
14137 shadowed_labels = p->shadowed_labels;
14138 current_binding_level = p->binding_level;
14143 /* Save and reinitialize the variables
14144 used during compilation of a C function. */
14147 push_f_function_context ()
14149 struct f_function *p
14150 = (struct f_function *) xmalloc (sizeof (struct f_function));
14152 push_function_context ();
14154 p->next = f_function_chain;
14155 f_function_chain = p;
14157 p->named_labels = named_labels;
14158 p->shadowed_labels = shadowed_labels;
14159 p->binding_level = current_binding_level;
14163 push_parm_decl (tree parm)
14165 int old_immediate_size_expand = immediate_size_expand;
14167 /* Don't try computing parm sizes now -- wait till fn is called. */
14169 immediate_size_expand = 0;
14171 /* Fill in arg stuff. */
14173 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
14174 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
14175 TREE_READONLY (parm) = 1; /* All implementation args are read-only. */
14177 parm = pushdecl (parm);
14179 immediate_size_expand = old_immediate_size_expand;
14181 finish_decl (parm, NULL_TREE, FALSE);
14184 /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
14187 pushdecl_top_level (x)
14191 register struct binding_level *b = current_binding_level;
14192 register tree f = current_function_decl;
14194 current_binding_level = global_binding_level;
14195 current_function_decl = NULL_TREE;
14197 current_binding_level = b;
14198 current_function_decl = f;
14202 /* Store the list of declarations of the current level.
14203 This is done for the parameter declarations of a function being defined,
14204 after they are modified in the light of any missing parameters. */
14210 return current_binding_level->names = decls;
14213 /* Store the parameter declarations into the current function declaration.
14214 This is called after parsing the parameter declarations, before
14215 digesting the body of the function.
14217 For an old-style definition, modify the function's type
14218 to specify at least the number of arguments. */
14221 store_parm_decls (int is_main_program UNUSED)
14223 register tree fndecl = current_function_decl;
14225 if (fndecl == error_mark_node)
14228 /* This is a chain of PARM_DECLs from old-style parm declarations. */
14229 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
14231 /* Initialize the RTL code for the function. */
14233 init_function_start (fndecl, input_filename, lineno);
14235 /* Set up parameters and prepare for return, for the function. */
14237 expand_function_start (fndecl, 0);
14241 start_decl (tree decl, bool is_top_level)
14244 bool at_top_level = (current_binding_level == global_binding_level);
14245 bool top_level = is_top_level || at_top_level;
14247 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
14249 assert (!is_top_level || !at_top_level);
14251 if (DECL_INITIAL (decl) != NULL_TREE)
14253 assert (DECL_INITIAL (decl) == error_mark_node);
14254 assert (!DECL_EXTERNAL (decl));
14256 else if (top_level)
14257 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
14259 /* For Fortran, we by default put things in .common when possible. */
14260 DECL_COMMON (decl) = 1;
14262 /* Add this decl to the current binding level. TEM may equal DECL or it may
14263 be a previous decl of the same name. */
14265 tem = pushdecl_top_level (decl);
14267 tem = pushdecl (decl);
14269 /* For a local variable, define the RTL now. */
14271 /* But not if this is a duplicate decl and we preserved the rtl from the
14272 previous one (which may or may not happen). */
14273 && !DECL_RTL_SET_P (tem))
14275 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
14277 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
14278 && DECL_INITIAL (tem) != 0)
14285 /* Create the FUNCTION_DECL for a function definition.
14286 DECLSPECS and DECLARATOR are the parts of the declaration;
14287 they describe the function's name and the type it returns,
14288 but twisted together in a fashion that parallels the syntax of C.
14290 This function creates a binding context for the function body
14291 as well as setting up the FUNCTION_DECL in current_function_decl.
14293 Returns 1 on success. If the DECLARATOR is not suitable for a function
14294 (it defines a datum instead), we return 0, which tells
14295 yyparse to report a parse error.
14297 NESTED is nonzero for a function nested within another function. */
14300 start_function (tree name, tree type, int nested, int public)
14304 int old_immediate_size_expand = immediate_size_expand;
14307 shadowed_labels = 0;
14309 /* Don't expand any sizes in the return type of the function. */
14310 immediate_size_expand = 0;
14315 assert (current_function_decl != NULL_TREE);
14316 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
14320 assert (current_function_decl == NULL_TREE);
14323 if (TREE_CODE (type) == ERROR_MARK)
14324 decl1 = current_function_decl = error_mark_node;
14327 decl1 = build_decl (FUNCTION_DECL,
14330 TREE_PUBLIC (decl1) = public ? 1 : 0;
14332 DECL_INLINE (decl1) = 1;
14333 TREE_STATIC (decl1) = 1;
14334 DECL_EXTERNAL (decl1) = 0;
14336 announce_function (decl1);
14338 /* Make the init_value nonzero so pushdecl knows this is not tentative.
14339 error_mark_node is replaced below (in poplevel) with the BLOCK. */
14340 DECL_INITIAL (decl1) = error_mark_node;
14342 /* Record the decl so that the function name is defined. If we already have
14343 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
14345 current_function_decl = pushdecl (decl1);
14349 ffecom_outer_function_decl_ = current_function_decl;
14352 current_binding_level->prep_state = 2;
14354 if (TREE_CODE (current_function_decl) != ERROR_MARK)
14356 make_decl_rtl (current_function_decl, NULL);
14358 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14359 DECL_RESULT (current_function_decl)
14360 = build_decl (RESULT_DECL, NULL_TREE, restype);
14363 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14364 TREE_ADDRESSABLE (current_function_decl) = 1;
14366 immediate_size_expand = old_immediate_size_expand;
14369 /* Here are the public functions the GNU back end needs. */
14372 convert (type, expr)
14375 register tree e = expr;
14376 register enum tree_code code = TREE_CODE (type);
14378 if (type == TREE_TYPE (e)
14379 || TREE_CODE (e) == ERROR_MARK)
14381 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14382 return fold (build1 (NOP_EXPR, type, e));
14383 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14384 || code == ERROR_MARK)
14385 return error_mark_node;
14386 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14388 assert ("void value not ignored as it ought to be" == NULL);
14389 return error_mark_node;
14391 if (code == VOID_TYPE)
14392 return build1 (CONVERT_EXPR, type, e);
14393 if ((code != RECORD_TYPE)
14394 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14395 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14397 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14398 return fold (convert_to_integer (type, e));
14399 if (code == POINTER_TYPE)
14400 return fold (convert_to_pointer (type, e));
14401 if (code == REAL_TYPE)
14402 return fold (convert_to_real (type, e));
14403 if (code == COMPLEX_TYPE)
14404 return fold (convert_to_complex (type, e));
14405 if (code == RECORD_TYPE)
14406 return fold (ffecom_convert_to_complex_ (type, e));
14408 assert ("conversion to non-scalar type requested" == NULL);
14409 return error_mark_node;
14412 /* integrate_decl_tree calls this function, but since we don't use the
14413 DECL_LANG_SPECIFIC field, this is a no-op. */
14416 copy_lang_decl (node)
14421 /* Return the list of declarations of the current level.
14422 Note that this list is in reverse order unless/until
14423 you nreverse it; and when you do nreverse it, you must
14424 store the result back using `storedecls' or you will lose. */
14429 return current_binding_level->names;
14432 /* Nonzero if we are currently in the global binding level. */
14435 global_bindings_p ()
14437 return current_binding_level == global_binding_level;
14440 /* Print an error message for invalid use of an incomplete type.
14441 VALUE is the expression that was used (or 0 if that isn't known)
14442 and TYPE is the type that was invalid. */
14445 incomplete_type_error (value, type)
14449 if (TREE_CODE (type) == ERROR_MARK)
14452 assert ("incomplete type?!?" == NULL);
14455 /* Mark ARG for GC. */
14457 mark_binding_level (void *arg)
14459 struct binding_level *level = *(struct binding_level **) arg;
14463 ggc_mark_tree (level->names);
14464 ggc_mark_tree (level->blocks);
14465 ggc_mark_tree (level->this_block);
14466 level = level->level_chain;
14471 init_decl_processing ()
14473 static tree *const tree_roots[] = {
14474 ¤t_function_decl,
14476 &ffecom_tree_fun_type_void,
14477 &ffecom_integer_zero_node,
14478 &ffecom_integer_one_node,
14479 &ffecom_tree_subr_type,
14480 &ffecom_tree_ptr_to_subr_type,
14481 &ffecom_tree_blockdata_type,
14482 &ffecom_tree_xargc_,
14483 &ffecom_f2c_integer_type_node,
14484 &ffecom_f2c_ptr_to_integer_type_node,
14485 &ffecom_f2c_address_type_node,
14486 &ffecom_f2c_real_type_node,
14487 &ffecom_f2c_ptr_to_real_type_node,
14488 &ffecom_f2c_doublereal_type_node,
14489 &ffecom_f2c_complex_type_node,
14490 &ffecom_f2c_doublecomplex_type_node,
14491 &ffecom_f2c_longint_type_node,
14492 &ffecom_f2c_logical_type_node,
14493 &ffecom_f2c_flag_type_node,
14494 &ffecom_f2c_ftnlen_type_node,
14495 &ffecom_f2c_ftnlen_zero_node,
14496 &ffecom_f2c_ftnlen_one_node,
14497 &ffecom_f2c_ftnlen_two_node,
14498 &ffecom_f2c_ptr_to_ftnlen_type_node,
14499 &ffecom_f2c_ftnint_type_node,
14500 &ffecom_f2c_ptr_to_ftnint_type_node,
14501 &ffecom_outer_function_decl_,
14502 &ffecom_previous_function_decl_,
14503 &ffecom_which_entrypoint_decl_,
14504 &ffecom_float_zero_,
14505 &ffecom_float_half_,
14506 &ffecom_double_zero_,
14507 &ffecom_double_half_,
14508 &ffecom_func_result_,
14509 &ffecom_func_length_,
14510 &ffecom_multi_type_node_,
14511 &ffecom_multi_retval_,
14519 /* Record our roots. */
14520 for (i = 0; i < ARRAY_SIZE (tree_roots); i++)
14521 ggc_add_tree_root (tree_roots[i], 1);
14522 ggc_add_tree_root (&ffecom_tree_type[0][0],
14523 FFEINFO_basictype*FFEINFO_kindtype);
14524 ggc_add_tree_root (&ffecom_tree_fun_type[0][0],
14525 FFEINFO_basictype*FFEINFO_kindtype);
14526 ggc_add_tree_root (&ffecom_tree_ptr_to_fun_type[0][0],
14527 FFEINFO_basictype*FFEINFO_kindtype);
14528 ggc_add_tree_root (ffecom_gfrt_, FFECOM_gfrt);
14529 ggc_add_root (¤t_binding_level, 1, sizeof current_binding_level,
14530 mark_binding_level);
14531 ggc_add_root (&free_binding_level, 1, sizeof current_binding_level,
14532 mark_binding_level);
14533 ggc_add_root (&tracker_head, 1, sizeof tracker_head, mark_tracker_head);
14539 init_parse (filename)
14540 const char *filename;
14542 /* Open input file. */
14543 if (filename == 0 || !strcmp (filename, "-"))
14546 filename = "stdin";
14549 finput = fopen (filename, "r");
14551 fatal_io_error ("can't open %s", filename);
14553 #ifdef IO_BUFFER_SIZE
14554 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14557 /* Make identifier nodes long enough for the language-specific slots. */
14558 set_identifier_size (sizeof (struct lang_identifier));
14559 decl_printable_name = lang_printable_name;
14561 print_error_function = lang_print_error_function;
14573 /* Delete the node BLOCK from the current binding level.
14574 This is used for the block inside a stmt expr ({...})
14575 so that the block can be reinserted where appropriate. */
14578 delete_block (block)
14582 if (current_binding_level->blocks == block)
14583 current_binding_level->blocks = TREE_CHAIN (block);
14584 for (t = current_binding_level->blocks; t;)
14586 if (TREE_CHAIN (t) == block)
14587 TREE_CHAIN (t) = TREE_CHAIN (block);
14589 t = TREE_CHAIN (t);
14591 TREE_CHAIN (block) = NULL;
14592 /* Clear TREE_USED which is always set by poplevel.
14593 The flag is set again if insert_block is called. */
14594 TREE_USED (block) = 0;
14598 insert_block (block)
14601 TREE_USED (block) = 1;
14602 current_binding_level->blocks
14603 = chainon (current_binding_level->blocks, block);
14606 /* Each front end provides its own. */
14607 static void ffe_init PARAMS ((void));
14608 static void ffe_finish PARAMS ((void));
14609 static void ffe_init_options PARAMS ((void));
14611 struct lang_hooks lang_hooks = {ffe_init,
14615 NULL /* post_options */};
14617 /* used by print-tree.c */
14620 lang_print_xnode (file, node, indent)
14630 ffe_terminate_0 ();
14632 if (ffe_is_ffedebug ())
14633 malloc_pool_display (malloc_pool_image ());
14642 /* Return the typed-based alias set for T, which may be an expression
14643 or a type. Return -1 if we don't do anything special. */
14646 lang_get_alias_set (t)
14647 tree t ATTRIBUTE_UNUSED;
14649 /* We do not wish to use alias-set based aliasing at all. Used in the
14650 extreme (every object with its own set, with equivalences recorded)
14651 it might be helpful, but there are problems when it comes to inlining.
14652 We get on ok with flag_argument_noalias, and alias-set aliasing does
14653 currently limit how stack slots can be reused, which is a lose. */
14658 ffe_init_options ()
14660 /* Set default options for Fortran. */
14661 flag_move_all_movables = 1;
14662 flag_reduce_all_givs = 1;
14663 flag_argument_noalias = 2;
14664 flag_errno_math = 0;
14665 flag_complex_divide_method = 1;
14671 /* If the file is output from cpp, it should contain a first line
14672 `# 1 "real-filename"', and the current design of gcc (toplev.c
14673 in particular and the way it sets up information relied on by
14674 INCLUDE) requires that we read this now, and store the
14675 "real-filename" info in master_input_filename. Ask the lexer
14676 to try doing this. */
14677 ffelex_hash_kludge (finput);
14681 mark_addressable (exp)
14684 register tree x = exp;
14686 switch (TREE_CODE (x))
14689 case COMPONENT_REF:
14691 x = TREE_OPERAND (x, 0);
14695 TREE_ADDRESSABLE (x) = 1;
14702 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14703 && DECL_NONLOCAL (x))
14705 if (TREE_PUBLIC (x))
14707 assert ("address of global register var requested" == NULL);
14710 assert ("address of register variable requested" == NULL);
14712 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14714 if (TREE_PUBLIC (x))
14716 assert ("address of global register var requested" == NULL);
14719 assert ("address of register var requested" == NULL);
14721 put_var_into_stack (x);
14724 case FUNCTION_DECL:
14725 TREE_ADDRESSABLE (x) = 1;
14726 #if 0 /* poplevel deals with this now. */
14727 if (DECL_CONTEXT (x) == 0)
14728 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14736 /* If DECL has a cleanup, build and return that cleanup here.
14737 This is a callback called by expand_expr. */
14740 maybe_build_cleanup (decl)
14743 /* There are no cleanups in Fortran. */
14747 /* Exit a binding level.
14748 Pop the level off, and restore the state of the identifier-decl mappings
14749 that were in effect when this level was entered.
14751 If KEEP is nonzero, this level had explicit declarations, so
14752 and create a "block" (a BLOCK node) for the level
14753 to record its declarations and subblocks for symbol table output.
14755 If FUNCTIONBODY is nonzero, this level is the body of a function,
14756 so create a block as if KEEP were set and also clear out all
14759 If REVERSE is nonzero, reverse the order of decls before putting
14760 them into the BLOCK. */
14763 poplevel (keep, reverse, functionbody)
14768 register tree link;
14769 /* The chain of decls was accumulated in reverse order.
14770 Put it into forward order, just for cleanliness. */
14772 tree subblocks = current_binding_level->blocks;
14775 int block_previously_created;
14777 /* Get the decls in the order they were written.
14778 Usually current_binding_level->names is in reverse order.
14779 But parameter decls were previously put in forward order. */
14782 current_binding_level->names
14783 = decls = nreverse (current_binding_level->names);
14785 decls = current_binding_level->names;
14787 /* Output any nested inline functions within this block
14788 if they weren't already output. */
14790 for (decl = decls; decl; decl = TREE_CHAIN (decl))
14791 if (TREE_CODE (decl) == FUNCTION_DECL
14792 && ! TREE_ASM_WRITTEN (decl)
14793 && DECL_INITIAL (decl) != 0
14794 && TREE_ADDRESSABLE (decl))
14796 /* If this decl was copied from a file-scope decl
14797 on account of a block-scope extern decl,
14798 propagate TREE_ADDRESSABLE to the file-scope decl.
14800 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
14801 true, since then the decl goes through save_for_inline_copying. */
14802 if (DECL_ABSTRACT_ORIGIN (decl) != 0
14803 && DECL_ABSTRACT_ORIGIN (decl) != decl)
14804 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
14805 else if (DECL_SAVED_INSNS (decl) != 0)
14807 push_function_context ();
14808 output_inline_function (decl);
14809 pop_function_context ();
14813 /* If there were any declarations or structure tags in that level,
14814 or if this level is a function body,
14815 create a BLOCK to record them for the life of this function. */
14818 block_previously_created = (current_binding_level->this_block != 0);
14819 if (block_previously_created)
14820 block = current_binding_level->this_block;
14821 else if (keep || functionbody)
14822 block = make_node (BLOCK);
14825 BLOCK_VARS (block) = decls;
14826 BLOCK_SUBBLOCKS (block) = subblocks;
14829 /* In each subblock, record that this is its superior. */
14831 for (link = subblocks; link; link = TREE_CHAIN (link))
14832 BLOCK_SUPERCONTEXT (link) = block;
14834 /* Clear out the meanings of the local variables of this level. */
14836 for (link = decls; link; link = TREE_CHAIN (link))
14838 if (DECL_NAME (link) != 0)
14840 /* If the ident. was used or addressed via a local extern decl,
14841 don't forget that fact. */
14842 if (DECL_EXTERNAL (link))
14844 if (TREE_USED (link))
14845 TREE_USED (DECL_NAME (link)) = 1;
14846 if (TREE_ADDRESSABLE (link))
14847 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
14849 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
14853 /* If the level being exited is the top level of a function,
14854 check over all the labels, and clear out the current
14855 (function local) meanings of their names. */
14859 /* If this is the top level block of a function,
14860 the vars are the function's parameters.
14861 Don't leave them in the BLOCK because they are
14862 found in the FUNCTION_DECL instead. */
14864 BLOCK_VARS (block) = 0;
14867 /* Pop the current level, and free the structure for reuse. */
14870 register struct binding_level *level = current_binding_level;
14871 current_binding_level = current_binding_level->level_chain;
14873 level->level_chain = free_binding_level;
14874 free_binding_level = level;
14877 /* Dispose of the block that we just made inside some higher level. */
14879 && current_function_decl != error_mark_node)
14880 DECL_INITIAL (current_function_decl) = block;
14883 if (!block_previously_created)
14884 current_binding_level->blocks
14885 = chainon (current_binding_level->blocks, block);
14887 /* If we did not make a block for the level just exited,
14888 any blocks made for inner levels
14889 (since they cannot be recorded as subblocks in that level)
14890 must be carried forward so they will later become subblocks
14891 of something else. */
14892 else if (subblocks)
14893 current_binding_level->blocks
14894 = chainon (current_binding_level->blocks, subblocks);
14897 TREE_USED (block) = 1;
14902 print_lang_decl (file, node, indent)
14910 print_lang_identifier (file, node, indent)
14915 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
14916 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
14920 print_lang_statistics ()
14925 print_lang_type (file, node, indent)
14932 /* Record a decl-node X as belonging to the current lexical scope.
14933 Check for errors (such as an incompatible declaration for the same
14934 name already seen in the same scope).
14936 Returns either X or an old decl for the same name.
14937 If an old decl is returned, it may have been smashed
14938 to agree with what X says. */
14945 register tree name = DECL_NAME (x);
14946 register struct binding_level *b = current_binding_level;
14948 if ((TREE_CODE (x) == FUNCTION_DECL)
14949 && (DECL_INITIAL (x) == 0)
14950 && DECL_EXTERNAL (x))
14951 DECL_CONTEXT (x) = NULL_TREE;
14953 DECL_CONTEXT (x) = current_function_decl;
14957 if (IDENTIFIER_INVENTED (name))
14960 DECL_ARTIFICIAL (x) = 1;
14962 DECL_IN_SYSTEM_HEADER (x) = 1;
14965 t = lookup_name_current_level (name);
14967 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
14969 /* Don't push non-parms onto list for parms until we understand
14970 why we're doing this and whether it works. */
14972 assert ((b == global_binding_level)
14973 || !ffecom_transform_only_dummies_
14974 || TREE_CODE (x) == PARM_DECL);
14976 if ((t != NULL_TREE) && duplicate_decls (x, t))
14979 /* If we are processing a typedef statement, generate a whole new
14980 ..._TYPE node (which will be just an variant of the existing
14981 ..._TYPE node with identical properties) and then install the
14982 TYPE_DECL node generated to represent the typedef name as the
14983 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
14985 The whole point here is to end up with a situation where each and every
14986 ..._TYPE node the compiler creates will be uniquely associated with
14987 AT MOST one node representing a typedef name. This way, even though
14988 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
14989 (i.e. "typedef name") nodes very early on, later parts of the
14990 compiler can always do the reverse translation and get back the
14991 corresponding typedef name. For example, given:
14993 typedef struct S MY_TYPE; MY_TYPE object;
14995 Later parts of the compiler might only know that `object' was of type
14996 `struct S' if it were not for code just below. With this code
14997 however, later parts of the compiler see something like:
14999 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
15001 And they can then deduce (from the node for type struct S') that the
15002 original object declaration was:
15006 Being able to do this is important for proper support of protoize, and
15007 also for generating precise symbolic debugging information which
15008 takes full account of the programmer's (typedef) vocabulary.
15010 Obviously, we don't want to generate a duplicate ..._TYPE node if the
15011 TYPE_DECL node that we are now processing really represents a
15012 standard built-in type.
15014 Since all standard types are effectively declared at line zero in the
15015 source file, we can easily check to see if we are working on a
15016 standard type by checking the current value of lineno. */
15018 if (TREE_CODE (x) == TYPE_DECL)
15020 if (DECL_SOURCE_LINE (x) == 0)
15022 if (TYPE_NAME (TREE_TYPE (x)) == 0)
15023 TYPE_NAME (TREE_TYPE (x)) = x;
15025 else if (TREE_TYPE (x) != error_mark_node)
15027 tree tt = TREE_TYPE (x);
15029 tt = build_type_copy (tt);
15030 TYPE_NAME (tt) = x;
15031 TREE_TYPE (x) = tt;
15035 /* This name is new in its binding level. Install the new declaration
15037 if (b == global_binding_level)
15038 IDENTIFIER_GLOBAL_VALUE (name) = x;
15040 IDENTIFIER_LOCAL_VALUE (name) = x;
15043 /* Put decls on list in reverse order. We will reverse them later if
15045 TREE_CHAIN (x) = b->names;
15051 /* Nonzero if the current level needs to have a BLOCK made. */
15058 for (decl = current_binding_level->names;
15060 decl = TREE_CHAIN (decl))
15062 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
15063 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
15064 /* Currently, there aren't supposed to be non-artificial names
15065 at other than the top block for a function -- they're
15066 believed to always be temps. But it's wise to check anyway. */
15072 /* Enter a new binding level.
15073 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
15074 not for that of tags. */
15077 pushlevel (tag_transparent)
15078 int tag_transparent;
15080 register struct binding_level *newlevel = NULL_BINDING_LEVEL;
15082 assert (! tag_transparent);
15084 if (current_binding_level == global_binding_level)
15089 /* Reuse or create a struct for this binding level. */
15091 if (free_binding_level)
15093 newlevel = free_binding_level;
15094 free_binding_level = free_binding_level->level_chain;
15098 newlevel = make_binding_level ();
15101 /* Add this level to the front of the chain (stack) of levels that
15104 *newlevel = clear_binding_level;
15105 newlevel->level_chain = current_binding_level;
15106 current_binding_level = newlevel;
15109 /* Set the BLOCK node for the innermost scope
15110 (the one we are currently in). */
15114 register tree block;
15116 current_binding_level->this_block = block;
15117 current_binding_level->names = chainon (current_binding_level->names,
15118 BLOCK_VARS (block));
15119 current_binding_level->blocks = chainon (current_binding_level->blocks,
15120 BLOCK_SUBBLOCKS (block));
15123 /* ~~gcc/tree.h *should* declare this, because toplev.c references it. */
15125 /* Can't 'yydebug' a front end not generated by yacc/bison! */
15128 set_yydebug (value)
15132 fprintf (stderr, "warning: no yacc/bison-generated output to debug!\n");
15136 signed_or_unsigned_type (unsignedp, type)
15142 if (! INTEGRAL_TYPE_P (type))
15144 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
15145 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15146 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
15147 return unsignedp ? unsigned_type_node : integer_type_node;
15148 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
15149 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15150 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
15151 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15152 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
15153 return (unsignedp ? long_long_unsigned_type_node
15154 : long_long_integer_type_node);
15156 type2 = type_for_size (TYPE_PRECISION (type), unsignedp);
15157 if (type2 == NULL_TREE)
15167 tree type1 = TYPE_MAIN_VARIANT (type);
15168 ffeinfoKindtype kt;
15171 if (type1 == unsigned_char_type_node || type1 == char_type_node)
15172 return signed_char_type_node;
15173 if (type1 == unsigned_type_node)
15174 return integer_type_node;
15175 if (type1 == short_unsigned_type_node)
15176 return short_integer_type_node;
15177 if (type1 == long_unsigned_type_node)
15178 return long_integer_type_node;
15179 if (type1 == long_long_unsigned_type_node)
15180 return long_long_integer_type_node;
15181 #if 0 /* gcc/c-* files only */
15182 if (type1 == unsigned_intDI_type_node)
15183 return intDI_type_node;
15184 if (type1 == unsigned_intSI_type_node)
15185 return intSI_type_node;
15186 if (type1 == unsigned_intHI_type_node)
15187 return intHI_type_node;
15188 if (type1 == unsigned_intQI_type_node)
15189 return intQI_type_node;
15192 type2 = type_for_size (TYPE_PRECISION (type1), 0);
15193 if (type2 != NULL_TREE)
15196 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15198 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15200 if (type1 == type2)
15201 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15207 /* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
15208 or validate its data type for an `if' or `while' statement or ?..: exp.
15210 This preparation consists of taking the ordinary
15211 representation of an expression expr and producing a valid tree
15212 boolean expression describing whether expr is nonzero. We could
15213 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
15214 but we optimize comparisons, &&, ||, and !.
15216 The resulting type should always be `integer_type_node'. */
15219 truthvalue_conversion (expr)
15222 if (TREE_CODE (expr) == ERROR_MARK)
15225 #if 0 /* This appears to be wrong for C++. */
15226 /* These really should return error_mark_node after 2.4 is stable.
15227 But not all callers handle ERROR_MARK properly. */
15228 switch (TREE_CODE (TREE_TYPE (expr)))
15231 error ("struct type value used where scalar is required");
15232 return integer_zero_node;
15235 error ("union type value used where scalar is required");
15236 return integer_zero_node;
15239 error ("array type value used where scalar is required");
15240 return integer_zero_node;
15247 switch (TREE_CODE (expr))
15249 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15250 or comparison expressions as truth values at this level. */
15252 case COMPONENT_REF:
15253 /* A one-bit unsigned bit-field is already acceptable. */
15254 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
15255 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
15261 /* It is simpler and generates better code to have only TRUTH_*_EXPR
15262 or comparison expressions as truth values at this level. */
15264 if (integer_zerop (TREE_OPERAND (expr, 1)))
15265 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
15267 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
15268 case TRUTH_ANDIF_EXPR:
15269 case TRUTH_ORIF_EXPR:
15270 case TRUTH_AND_EXPR:
15271 case TRUTH_OR_EXPR:
15272 case TRUTH_XOR_EXPR:
15273 TREE_TYPE (expr) = integer_type_node;
15280 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
15283 return real_zerop (expr) ? integer_zero_node : integer_one_node;
15286 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
15287 return build (COMPOUND_EXPR, integer_type_node,
15288 TREE_OPERAND (expr, 0), integer_one_node);
15290 return integer_one_node;
15293 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
15294 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15296 truthvalue_conversion (TREE_OPERAND (expr, 0)),
15297 truthvalue_conversion (TREE_OPERAND (expr, 1)));
15303 /* These don't change whether an object is non-zero or zero. */
15304 return truthvalue_conversion (TREE_OPERAND (expr, 0));
15308 /* These don't change whether an object is zero or non-zero, but
15309 we can't ignore them if their second arg has side-effects. */
15310 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
15311 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
15312 truthvalue_conversion (TREE_OPERAND (expr, 0)));
15314 return truthvalue_conversion (TREE_OPERAND (expr, 0));
15317 /* Distribute the conversion into the arms of a COND_EXPR. */
15318 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
15319 truthvalue_conversion (TREE_OPERAND (expr, 1)),
15320 truthvalue_conversion (TREE_OPERAND (expr, 2))));
15323 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
15324 since that affects how `default_conversion' will behave. */
15325 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
15326 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
15328 /* fall through... */
15330 /* If this is widening the argument, we can ignore it. */
15331 if (TYPE_PRECISION (TREE_TYPE (expr))
15332 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
15333 return truthvalue_conversion (TREE_OPERAND (expr, 0));
15337 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
15339 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
15340 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
15342 /* fall through... */
15344 /* This and MINUS_EXPR can be changed into a comparison of the
15346 if (TREE_TYPE (TREE_OPERAND (expr, 0))
15347 == TREE_TYPE (TREE_OPERAND (expr, 1)))
15348 return ffecom_2 (NE_EXPR, integer_type_node,
15349 TREE_OPERAND (expr, 0),
15350 TREE_OPERAND (expr, 1));
15351 return ffecom_2 (NE_EXPR, integer_type_node,
15352 TREE_OPERAND (expr, 0),
15353 fold (build1 (NOP_EXPR,
15354 TREE_TYPE (TREE_OPERAND (expr, 0)),
15355 TREE_OPERAND (expr, 1))));
15358 if (integer_onep (TREE_OPERAND (expr, 1)))
15363 #if 0 /* No such thing in Fortran. */
15364 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
15365 warning ("suggest parentheses around assignment used as truth value");
15373 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
15375 ((TREE_SIDE_EFFECTS (expr)
15376 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
15378 truthvalue_conversion (ffecom_1 (REALPART_EXPR,
15379 TREE_TYPE (TREE_TYPE (expr)),
15381 truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
15382 TREE_TYPE (TREE_TYPE (expr)),
15385 return ffecom_2 (NE_EXPR, integer_type_node,
15387 convert (TREE_TYPE (expr), integer_zero_node));
15391 type_for_mode (mode, unsignedp)
15392 enum machine_mode mode;
15399 if (mode == TYPE_MODE (integer_type_node))
15400 return unsignedp ? unsigned_type_node : integer_type_node;
15402 if (mode == TYPE_MODE (signed_char_type_node))
15403 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15405 if (mode == TYPE_MODE (short_integer_type_node))
15406 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15408 if (mode == TYPE_MODE (long_integer_type_node))
15409 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15411 if (mode == TYPE_MODE (long_long_integer_type_node))
15412 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
15414 #if HOST_BITS_PER_WIDE_INT >= 64
15415 if (mode == TYPE_MODE (intTI_type_node))
15416 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
15419 if (mode == TYPE_MODE (float_type_node))
15420 return float_type_node;
15422 if (mode == TYPE_MODE (double_type_node))
15423 return double_type_node;
15425 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
15426 return build_pointer_type (char_type_node);
15428 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
15429 return build_pointer_type (integer_type_node);
15431 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
15432 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
15434 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
15435 && (mode == TYPE_MODE (t)))
15437 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
15438 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
15448 type_for_size (bits, unsignedp)
15452 ffeinfoKindtype kt;
15455 if (bits == TYPE_PRECISION (integer_type_node))
15456 return unsignedp ? unsigned_type_node : integer_type_node;
15458 if (bits == TYPE_PRECISION (signed_char_type_node))
15459 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15461 if (bits == TYPE_PRECISION (short_integer_type_node))
15462 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15464 if (bits == TYPE_PRECISION (long_integer_type_node))
15465 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15467 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15468 return (unsignedp ? long_long_unsigned_type_node
15469 : long_long_integer_type_node);
15471 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15473 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15475 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15476 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15484 unsigned_type (type)
15487 tree type1 = TYPE_MAIN_VARIANT (type);
15488 ffeinfoKindtype kt;
15491 if (type1 == signed_char_type_node || type1 == char_type_node)
15492 return unsigned_char_type_node;
15493 if (type1 == integer_type_node)
15494 return unsigned_type_node;
15495 if (type1 == short_integer_type_node)
15496 return short_unsigned_type_node;
15497 if (type1 == long_integer_type_node)
15498 return long_unsigned_type_node;
15499 if (type1 == long_long_integer_type_node)
15500 return long_long_unsigned_type_node;
15501 #if 0 /* gcc/c-* files only */
15502 if (type1 == intDI_type_node)
15503 return unsigned_intDI_type_node;
15504 if (type1 == intSI_type_node)
15505 return unsigned_intSI_type_node;
15506 if (type1 == intHI_type_node)
15507 return unsigned_intHI_type_node;
15508 if (type1 == intQI_type_node)
15509 return unsigned_intQI_type_node;
15512 type2 = type_for_size (TYPE_PRECISION (type1), 1);
15513 if (type2 != NULL_TREE)
15516 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15518 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15520 if (type1 == type2)
15521 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15529 union tree_node *t ATTRIBUTE_UNUSED;
15531 if (TREE_CODE (t) == IDENTIFIER_NODE)
15533 struct lang_identifier *i = (struct lang_identifier *) t;
15534 ggc_mark_tree (IDENTIFIER_GLOBAL_VALUE (i));
15535 ggc_mark_tree (IDENTIFIER_LOCAL_VALUE (i));
15536 ggc_mark_tree (IDENTIFIER_LABEL_VALUE (i));
15538 else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
15539 ggc_mark (TYPE_LANG_SPECIFIC (t));
15542 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
15544 #if FFECOM_GCC_INCLUDE
15546 /* From gcc/cccp.c, the code to handle -I. */
15548 /* Skip leading "./" from a directory name.
15549 This may yield the empty string, which represents the current directory. */
15551 static const char *
15552 skip_redundant_dir_prefix (const char *dir)
15554 while (dir[0] == '.' && dir[1] == '/')
15555 for (dir += 2; *dir == '/'; dir++)
15557 if (dir[0] == '.' && !dir[1])
15562 /* The file_name_map structure holds a mapping of file names for a
15563 particular directory. This mapping is read from the file named
15564 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15565 map filenames on a file system with severe filename restrictions,
15566 such as DOS. The format of the file name map file is just a series
15567 of lines with two tokens on each line. The first token is the name
15568 to map, and the second token is the actual name to use. */
15570 struct file_name_map
15572 struct file_name_map *map_next;
15577 #define FILE_NAME_MAP_FILE "header.gcc"
15579 /* Current maximum length of directory names in the search path
15580 for include files. (Altered as we get more of them.) */
15582 static int max_include_len = 0;
15584 struct file_name_list
15586 struct file_name_list *next;
15588 /* Mapping of file names for this directory. */
15589 struct file_name_map *name_map;
15590 /* Non-zero if name_map is valid. */
15594 static struct file_name_list *include = NULL; /* First dir to search */
15595 static struct file_name_list *last_include = NULL; /* Last in chain */
15597 /* I/O buffer structure.
15598 The `fname' field is nonzero for source files and #include files
15599 and for the dummy text used for -D and -U.
15600 It is zero for rescanning results of macro expansion
15601 and for expanding macro arguments. */
15602 #define INPUT_STACK_MAX 400
15603 static struct file_buf {
15605 /* Filename specified with #line command. */
15606 const char *nominal_fname;
15607 /* Record where in the search path this file was found.
15608 For #include_next. */
15609 struct file_name_list *dir;
15611 ffewhereColumn column;
15612 } instack[INPUT_STACK_MAX];
15614 static int last_error_tick = 0; /* Incremented each time we print it. */
15615 static int input_file_stack_tick = 0; /* Incremented when status changes. */
15617 /* Current nesting level of input sources.
15618 `instack[indepth]' is the level currently being read. */
15619 static int indepth = -1;
15621 typedef struct file_buf FILE_BUF;
15623 typedef unsigned char U_CHAR;
15625 /* table to tell if char can be part of a C identifier. */
15626 U_CHAR is_idchar[256];
15627 /* table to tell if char can be first char of a c identifier. */
15628 U_CHAR is_idstart[256];
15629 /* table to tell if c is horizontal space. */
15630 U_CHAR is_hor_space[256];
15631 /* table to tell if c is horizontal or vertical space. */
15632 static U_CHAR is_space[256];
15634 #define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
15635 #define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
15637 /* Nonzero means -I- has been seen,
15638 so don't look for #include "foo" the source-file directory. */
15639 static int ignore_srcdir;
15641 #ifndef INCLUDE_LEN_FUDGE
15642 #define INCLUDE_LEN_FUDGE 0
15645 static void append_include_chain (struct file_name_list *first,
15646 struct file_name_list *last);
15647 static FILE *open_include_file (char *filename,
15648 struct file_name_list *searchptr);
15649 static void print_containing_files (ffebadSeverity sev);
15650 static char *read_filename_string (int ch, FILE *f);
15651 static struct file_name_map *read_name_map (const char *dirname);
15653 /* Append a chain of `struct file_name_list's
15654 to the end of the main include chain.
15655 FIRST is the beginning of the chain to append, and LAST is the end. */
15658 append_include_chain (first, last)
15659 struct file_name_list *first, *last;
15661 struct file_name_list *dir;
15663 if (!first || !last)
15669 last_include->next = first;
15671 for (dir = first; ; dir = dir->next) {
15672 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15673 if (len > max_include_len)
15674 max_include_len = len;
15680 last_include = last;
15683 /* Try to open include file FILENAME. SEARCHPTR is the directory
15684 being tried from the include file search path. This function maps
15685 filenames on file systems based on information read by
15689 open_include_file (filename, searchptr)
15691 struct file_name_list *searchptr;
15693 register struct file_name_map *map;
15694 register char *from;
15697 if (searchptr && ! searchptr->got_name_map)
15699 searchptr->name_map = read_name_map (searchptr->fname
15700 ? searchptr->fname : ".");
15701 searchptr->got_name_map = 1;
15704 /* First check the mapping for the directory we are using. */
15705 if (searchptr && searchptr->name_map)
15708 if (searchptr->fname)
15709 from += strlen (searchptr->fname) + 1;
15710 for (map = searchptr->name_map; map; map = map->map_next)
15712 if (! strcmp (map->map_from, from))
15714 /* Found a match. */
15715 return fopen (map->map_to, "r");
15720 /* Try to find a mapping file for the particular directory we are
15721 looking in. Thus #include <sys/types.h> will look up sys/types.h
15722 in /usr/include/header.gcc and look up types.h in
15723 /usr/include/sys/header.gcc. */
15724 p = strrchr (filename, '/');
15725 #ifdef DIR_SEPARATOR
15726 if (! p) p = strrchr (filename, DIR_SEPARATOR);
15728 char *tmp = strrchr (filename, DIR_SEPARATOR);
15729 if (tmp != NULL && tmp > p) p = tmp;
15735 && searchptr->fname
15736 && strlen (searchptr->fname) == (size_t) (p - filename)
15737 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15739 /* FILENAME is in SEARCHPTR, which we've already checked. */
15740 return fopen (filename, "r");
15746 map = read_name_map (".");
15750 dir = (char *) xmalloc (p - filename + 1);
15751 memcpy (dir, filename, p - filename);
15752 dir[p - filename] = '\0';
15754 map = read_name_map (dir);
15757 for (; map; map = map->map_next)
15758 if (! strcmp (map->map_from, from))
15759 return fopen (map->map_to, "r");
15761 return fopen (filename, "r");
15764 /* Print the file names and line numbers of the #include
15765 commands which led to the current file. */
15768 print_containing_files (ffebadSeverity sev)
15770 FILE_BUF *ip = NULL;
15776 /* If stack of files hasn't changed since we last printed
15777 this info, don't repeat it. */
15778 if (last_error_tick == input_file_stack_tick)
15781 for (i = indepth; i >= 0; i--)
15782 if (instack[i].fname != NULL) {
15787 /* Give up if we don't find a source file. */
15791 /* Find the other, outer source files. */
15792 for (i--; i >= 0; i--)
15793 if (instack[i].fname != NULL)
15799 str1 = "In file included";
15811 ffebad_start_msg ("%A from %B at %0%C", sev);
15812 ffebad_here (0, ip->line, ip->column);
15813 ffebad_string (str1);
15814 ffebad_string (ip->nominal_fname);
15815 ffebad_string (str2);
15819 /* Record we have printed the status as of this time. */
15820 last_error_tick = input_file_stack_tick;
15823 /* Read a space delimited string of unlimited length from a stdio
15827 read_filename_string (ch, f)
15835 set = alloc = xmalloc (len + 1);
15836 if (! is_space[ch])
15839 while ((ch = getc (f)) != EOF && ! is_space[ch])
15841 if (set - alloc == len)
15844 alloc = xrealloc (alloc, len + 1);
15845 set = alloc + len / 2;
15855 /* Read the file name map file for DIRNAME. */
15857 static struct file_name_map *
15858 read_name_map (dirname)
15859 const char *dirname;
15861 /* This structure holds a linked list of file name maps, one per
15863 struct file_name_map_list
15865 struct file_name_map_list *map_list_next;
15866 char *map_list_name;
15867 struct file_name_map *map_list_map;
15869 static struct file_name_map_list *map_list;
15870 register struct file_name_map_list *map_list_ptr;
15874 int separator_needed;
15876 dirname = skip_redundant_dir_prefix (dirname);
15878 for (map_list_ptr = map_list; map_list_ptr;
15879 map_list_ptr = map_list_ptr->map_list_next)
15880 if (! strcmp (map_list_ptr->map_list_name, dirname))
15881 return map_list_ptr->map_list_map;
15883 map_list_ptr = ((struct file_name_map_list *)
15884 xmalloc (sizeof (struct file_name_map_list)));
15885 map_list_ptr->map_list_name = xstrdup (dirname);
15886 map_list_ptr->map_list_map = NULL;
15888 dirlen = strlen (dirname);
15889 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
15890 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
15891 strcpy (name, dirname);
15892 name[dirlen] = '/';
15893 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
15894 f = fopen (name, "r");
15897 map_list_ptr->map_list_map = NULL;
15902 while ((ch = getc (f)) != EOF)
15905 struct file_name_map *ptr;
15909 from = read_filename_string (ch, f);
15910 while ((ch = getc (f)) != EOF && is_hor_space[ch])
15912 to = read_filename_string (ch, f);
15914 ptr = ((struct file_name_map *)
15915 xmalloc (sizeof (struct file_name_map)));
15916 ptr->map_from = from;
15918 /* Make the real filename absolute. */
15923 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
15924 strcpy (ptr->map_to, dirname);
15925 ptr->map_to[dirlen] = '/';
15926 strcpy (ptr->map_to + dirlen + separator_needed, to);
15930 ptr->map_next = map_list_ptr->map_list_map;
15931 map_list_ptr->map_list_map = ptr;
15933 while ((ch = getc (f)) != '\n')
15940 map_list_ptr->map_list_next = map_list;
15941 map_list = map_list_ptr;
15943 return map_list_ptr->map_list_map;
15947 ffecom_file_ (const char *name)
15951 /* Do partial setup of input buffer for the sake of generating
15952 early #line directives (when -g is in effect). */
15954 fp = &instack[++indepth];
15955 memset ((char *) fp, 0, sizeof (FILE_BUF));
15958 fp->nominal_fname = fp->fname = name;
15961 /* Initialize syntactic classifications of characters. */
15964 ffecom_initialize_char_syntax_ ()
15969 * Set up is_idchar and is_idstart tables. These should be
15970 * faster than saying (is_alpha (c) || c == '_'), etc.
15971 * Set up these things before calling any routines tthat
15974 for (i = 'a'; i <= 'z'; i++) {
15975 is_idchar[i - 'a' + 'A'] = 1;
15977 is_idstart[i - 'a' + 'A'] = 1;
15980 for (i = '0'; i <= '9'; i++)
15982 is_idchar['_'] = 1;
15983 is_idstart['_'] = 1;
15985 /* horizontal space table */
15986 is_hor_space[' '] = 1;
15987 is_hor_space['\t'] = 1;
15988 is_hor_space['\v'] = 1;
15989 is_hor_space['\f'] = 1;
15990 is_hor_space['\r'] = 1;
15993 is_space['\t'] = 1;
15994 is_space['\v'] = 1;
15995 is_space['\f'] = 1;
15996 is_space['\n'] = 1;
15997 is_space['\r'] = 1;
16001 ffecom_close_include_ (FILE *f)
16006 input_file_stack_tick++;
16008 ffewhere_line_kill (instack[indepth].line);
16009 ffewhere_column_kill (instack[indepth].column);
16013 ffecom_decode_include_option_ (char *spec)
16015 struct file_name_list *dirtmp;
16017 if (! ignore_srcdir && !strcmp (spec, "-"))
16021 dirtmp = (struct file_name_list *)
16022 xmalloc (sizeof (struct file_name_list));
16023 dirtmp->next = 0; /* New one goes on the end */
16024 dirtmp->fname = spec;
16025 dirtmp->got_name_map = 0;
16027 error ("Directory name must immediately follow -I");
16029 append_include_chain (dirtmp, dirtmp);
16034 /* Open INCLUDEd file. */
16037 ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
16040 size_t flen = strlen (fbeg);
16041 struct file_name_list *search_start = include; /* Chain of dirs to search */
16042 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
16043 struct file_name_list *searchptr = 0;
16044 char *fname; /* Dynamically allocated fname buffer */
16051 dsp[0].fname = NULL;
16053 /* If -I- was specified, don't search current dir, only spec'd ones. */
16054 if (!ignore_srcdir)
16056 for (fp = &instack[indepth]; fp >= instack; fp--)
16062 if ((nam = fp->nominal_fname) != NULL)
16064 /* Found a named file. Figure out dir of the file,
16065 and put it in front of the search list. */
16066 dsp[0].next = search_start;
16067 search_start = dsp;
16069 ep = strrchr (nam, '/');
16070 #ifdef DIR_SEPARATOR
16071 if (ep == NULL) ep = strrchr (nam, DIR_SEPARATOR);
16073 char *tmp = strrchr (nam, DIR_SEPARATOR);
16074 if (tmp != NULL && tmp > ep) ep = tmp;
16078 ep = strrchr (nam, ']');
16079 if (ep == NULL) ep = strrchr (nam, '>');
16080 if (ep == NULL) ep = strrchr (nam, ':');
16081 if (ep != NULL) ep++;
16086 dsp[0].fname = (char *) xmalloc (n + 1);
16087 strncpy (dsp[0].fname, nam, n);
16088 dsp[0].fname[n] = '\0';
16089 if (n + INCLUDE_LEN_FUDGE > max_include_len)
16090 max_include_len = n + INCLUDE_LEN_FUDGE;
16093 dsp[0].fname = NULL; /* Current directory */
16094 dsp[0].got_name_map = 0;
16100 /* Allocate this permanently, because it gets stored in the definitions
16102 fname = xmalloc (max_include_len + flen + 4);
16103 /* + 2 above for slash and terminating null. */
16104 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
16107 /* If specified file name is absolute, just open it. */
16110 #ifdef DIR_SEPARATOR
16111 || *fbeg == DIR_SEPARATOR
16115 strncpy (fname, (char *) fbeg, flen);
16117 f = open_include_file (fname, NULL);
16123 /* Search directory path, trying to open the file.
16124 Copy each filename tried into FNAME. */
16126 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
16128 if (searchptr->fname)
16130 /* The empty string in a search path is ignored.
16131 This makes it possible to turn off entirely
16132 a standard piece of the list. */
16133 if (searchptr->fname[0] == 0)
16135 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
16136 if (fname[0] && fname[strlen (fname) - 1] != '/')
16137 strcat (fname, "/");
16138 fname[strlen (fname) + flen] = 0;
16143 strncat (fname, fbeg, flen);
16145 /* Change this 1/2 Unix 1/2 VMS file specification into a
16146 full VMS file specification */
16147 if (searchptr->fname && (searchptr->fname[0] != 0))
16149 /* Fix up the filename */
16150 hack_vms_include_specification (fname);
16154 /* This is a normal VMS filespec, so use it unchanged. */
16155 strncpy (fname, (char *) fbeg, flen);
16157 #if 0 /* Not for g77. */
16158 /* if it's '#include filename', add the missing .h */
16159 if (strchr (fname, '.') == NULL)
16160 strcat (fname, ".h");
16164 f = open_include_file (fname, searchptr);
16166 if (f == NULL && errno == EACCES)
16168 print_containing_files (FFEBAD_severityWARNING);
16169 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
16170 FFEBAD_severityWARNING);
16171 ffebad_string (fname);
16172 ffebad_here (0, l, c);
16183 /* A file that was not found. */
16185 strncpy (fname, (char *) fbeg, flen);
16187 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
16188 ffebad_start (FFEBAD_OPEN_INCLUDE);
16189 ffebad_here (0, l, c);
16190 ffebad_string (fname);
16194 if (dsp[0].fname != NULL)
16195 free (dsp[0].fname);
16200 if (indepth >= (INPUT_STACK_MAX - 1))
16202 print_containing_files (FFEBAD_severityFATAL);
16203 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
16204 FFEBAD_severityFATAL);
16205 ffebad_string (fname);
16206 ffebad_here (0, l, c);
16211 instack[indepth].line = ffewhere_line_use (l);
16212 instack[indepth].column = ffewhere_column_use (c);
16214 fp = &instack[indepth + 1];
16215 memset ((char *) fp, 0, sizeof (FILE_BUF));
16216 fp->nominal_fname = fp->fname = fname;
16217 fp->dir = searchptr;
16220 input_file_stack_tick++;
16224 #endif /* FFECOM_GCC_INCLUDE */
16226 /**INDENT* (Do not reformat this comment even with -fca option.)
16227 Data-gathering files: Given the source file listed below, compiled with
16228 f2c I obtained the output file listed after that, and from the output
16229 file I derived the above code.
16231 -------- (begin input file to f2c)
16237 double precision D1,D2
16239 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
16266 c FFEINTRIN_impACOS
16267 call fooR(ACOS(R1))
16268 c FFEINTRIN_impAIMAG
16269 call fooR(AIMAG(C1))
16270 c FFEINTRIN_impAINT
16271 call fooR(AINT(R1))
16272 c FFEINTRIN_impALOG
16273 call fooR(ALOG(R1))
16274 c FFEINTRIN_impALOG10
16275 call fooR(ALOG10(R1))
16276 c FFEINTRIN_impAMAX0
16277 call fooR(AMAX0(I1,I2))
16278 c FFEINTRIN_impAMAX1
16279 call fooR(AMAX1(R1,R2))
16280 c FFEINTRIN_impAMIN0
16281 call fooR(AMIN0(I1,I2))
16282 c FFEINTRIN_impAMIN1
16283 call fooR(AMIN1(R1,R2))
16284 c FFEINTRIN_impAMOD
16285 call fooR(AMOD(R1,R2))
16286 c FFEINTRIN_impANINT
16287 call fooR(ANINT(R1))
16288 c FFEINTRIN_impASIN
16289 call fooR(ASIN(R1))
16290 c FFEINTRIN_impATAN
16291 call fooR(ATAN(R1))
16292 c FFEINTRIN_impATAN2
16293 call fooR(ATAN2(R1,R2))
16294 c FFEINTRIN_impCABS
16295 call fooR(CABS(C1))
16296 c FFEINTRIN_impCCOS
16297 call fooC(CCOS(C1))
16298 c FFEINTRIN_impCEXP
16299 call fooC(CEXP(C1))
16300 c FFEINTRIN_impCHAR
16301 call fooA(CHAR(I1))
16302 c FFEINTRIN_impCLOG
16303 call fooC(CLOG(C1))
16304 c FFEINTRIN_impCONJG
16305 call fooC(CONJG(C1))
16308 c FFEINTRIN_impCOSH
16309 call fooR(COSH(R1))
16310 c FFEINTRIN_impCSIN
16311 call fooC(CSIN(C1))
16312 c FFEINTRIN_impCSQRT
16313 call fooC(CSQRT(C1))
16314 c FFEINTRIN_impDABS
16315 call fooD(DABS(D1))
16316 c FFEINTRIN_impDACOS
16317 call fooD(DACOS(D1))
16318 c FFEINTRIN_impDASIN
16319 call fooD(DASIN(D1))
16320 c FFEINTRIN_impDATAN
16321 call fooD(DATAN(D1))
16322 c FFEINTRIN_impDATAN2
16323 call fooD(DATAN2(D1,D2))
16324 c FFEINTRIN_impDCOS
16325 call fooD(DCOS(D1))
16326 c FFEINTRIN_impDCOSH
16327 call fooD(DCOSH(D1))
16328 c FFEINTRIN_impDDIM
16329 call fooD(DDIM(D1,D2))
16330 c FFEINTRIN_impDEXP
16331 call fooD(DEXP(D1))
16333 call fooR(DIM(R1,R2))
16334 c FFEINTRIN_impDINT
16335 call fooD(DINT(D1))
16336 c FFEINTRIN_impDLOG
16337 call fooD(DLOG(D1))
16338 c FFEINTRIN_impDLOG10
16339 call fooD(DLOG10(D1))
16340 c FFEINTRIN_impDMAX1
16341 call fooD(DMAX1(D1,D2))
16342 c FFEINTRIN_impDMIN1
16343 call fooD(DMIN1(D1,D2))
16344 c FFEINTRIN_impDMOD
16345 call fooD(DMOD(D1,D2))
16346 c FFEINTRIN_impDNINT
16347 call fooD(DNINT(D1))
16348 c FFEINTRIN_impDPROD
16349 call fooD(DPROD(R1,R2))
16350 c FFEINTRIN_impDSIGN
16351 call fooD(DSIGN(D1,D2))
16352 c FFEINTRIN_impDSIN
16353 call fooD(DSIN(D1))
16354 c FFEINTRIN_impDSINH
16355 call fooD(DSINH(D1))
16356 c FFEINTRIN_impDSQRT
16357 call fooD(DSQRT(D1))
16358 c FFEINTRIN_impDTAN
16359 call fooD(DTAN(D1))
16360 c FFEINTRIN_impDTANH
16361 call fooD(DTANH(D1))
16364 c FFEINTRIN_impIABS
16365 call fooI(IABS(I1))
16366 c FFEINTRIN_impICHAR
16367 call fooI(ICHAR(A1))
16368 c FFEINTRIN_impIDIM
16369 call fooI(IDIM(I1,I2))
16370 c FFEINTRIN_impIDNINT
16371 call fooI(IDNINT(D1))
16372 c FFEINTRIN_impINDEX
16373 call fooI(INDEX(A1,A2))
16374 c FFEINTRIN_impISIGN
16375 call fooI(ISIGN(I1,I2))
16379 call fooL(LGE(A1,A2))
16381 call fooL(LGT(A1,A2))
16383 call fooL(LLE(A1,A2))
16385 call fooL(LLT(A1,A2))
16386 c FFEINTRIN_impMAX0
16387 call fooI(MAX0(I1,I2))
16388 c FFEINTRIN_impMAX1
16389 call fooI(MAX1(R1,R2))
16390 c FFEINTRIN_impMIN0
16391 call fooI(MIN0(I1,I2))
16392 c FFEINTRIN_impMIN1
16393 call fooI(MIN1(R1,R2))
16395 call fooI(MOD(I1,I2))
16396 c FFEINTRIN_impNINT
16397 call fooI(NINT(R1))
16398 c FFEINTRIN_impSIGN
16399 call fooR(SIGN(R1,R2))
16402 c FFEINTRIN_impSINH
16403 call fooR(SINH(R1))
16404 c FFEINTRIN_impSQRT
16405 call fooR(SQRT(R1))
16408 c FFEINTRIN_impTANH
16409 call fooR(TANH(R1))
16410 c FFEINTRIN_imp_CMPLX_C
16411 call fooC(cmplx(C1,C2))
16412 c FFEINTRIN_imp_CMPLX_D
16413 call fooZ(cmplx(D1,D2))
16414 c FFEINTRIN_imp_CMPLX_I
16415 call fooC(cmplx(I1,I2))
16416 c FFEINTRIN_imp_CMPLX_R
16417 call fooC(cmplx(R1,R2))
16418 c FFEINTRIN_imp_DBLE_C
16419 call fooD(dble(C1))
16420 c FFEINTRIN_imp_DBLE_D
16421 call fooD(dble(D1))
16422 c FFEINTRIN_imp_DBLE_I
16423 call fooD(dble(I1))
16424 c FFEINTRIN_imp_DBLE_R
16425 call fooD(dble(R1))
16426 c FFEINTRIN_imp_INT_C
16428 c FFEINTRIN_imp_INT_D
16430 c FFEINTRIN_imp_INT_I
16432 c FFEINTRIN_imp_INT_R
16434 c FFEINTRIN_imp_REAL_C
16435 call fooR(real(C1))
16436 c FFEINTRIN_imp_REAL_D
16437 call fooR(real(D1))
16438 c FFEINTRIN_imp_REAL_I
16439 call fooR(real(I1))
16440 c FFEINTRIN_imp_REAL_R
16441 call fooR(real(R1))
16443 c FFEINTRIN_imp_INT_D:
16445 c FFEINTRIN_specIDINT
16446 call fooI(IDINT(D1))
16448 c FFEINTRIN_imp_INT_R:
16450 c FFEINTRIN_specIFIX
16451 call fooI(IFIX(R1))
16452 c FFEINTRIN_specINT
16455 c FFEINTRIN_imp_REAL_D:
16457 c FFEINTRIN_specSNGL
16458 call fooR(SNGL(D1))
16460 c FFEINTRIN_imp_REAL_I:
16462 c FFEINTRIN_specFLOAT
16463 call fooR(FLOAT(I1))
16464 c FFEINTRIN_specREAL
16465 call fooR(REAL(I1))
16468 -------- (end input file to f2c)
16470 -------- (begin output from providing above input file as input to:
16471 -------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
16472 -------- -e "s:^#.*$::g"')
16474 // -- translated by f2c (version 19950223).
16475 You must link the resulting object file with the libraries:
16476 -lf2c -lm (in that order)
16480 // f2c.h -- Standard Fortran to C header file //
16482 /// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
16484 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
16489 // F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
16490 // we assume short, float are OK //
16491 typedef long int // long int // integer;
16492 typedef char *address;
16493 typedef short int shortint;
16494 typedef float real;
16495 typedef double doublereal;
16496 typedef struct { real r, i; } complex;
16497 typedef struct { doublereal r, i; } doublecomplex;
16498 typedef long int // long int // logical;
16499 typedef short int shortlogical;
16500 typedef char logical1;
16501 typedef char integer1;
16502 // typedef long long longint; // // system-dependent //
16507 // Extern is for use with -E //
16521 typedef long int // int or long int // flag;
16522 typedef long int // int or long int // ftnlen;
16523 typedef long int // int or long int // ftnint;
16526 //external read, write//
16535 //internal read, write//
16565 //rewind, backspace, endfile//
16577 ftnint *inex; //parameters in standard's order//
16603 union Multitype { // for multiple entry points //
16614 typedef union Multitype Multitype;
16616 typedef long Long; // No longer used; formerly in Namelist //
16618 struct Vardesc { // for Namelist //
16624 typedef struct Vardesc Vardesc;
16631 typedef struct Namelist Namelist;
16640 // procedure parameter types for -A and -C++ //
16645 typedef int // Unknown procedure type // (*U_fp)();
16646 typedef shortint (*J_fp)();
16647 typedef integer (*I_fp)();
16648 typedef real (*R_fp)();
16649 typedef doublereal (*D_fp)(), (*E_fp)();
16650 typedef // Complex // void (*C_fp)();
16651 typedef // Double Complex // void (*Z_fp)();
16652 typedef logical (*L_fp)();
16653 typedef shortlogical (*K_fp)();
16654 typedef // Character // void (*H_fp)();
16655 typedef // Subroutine // int (*S_fp)();
16657 // E_fp is for real functions when -R is not specified //
16658 typedef void C_f; // complex function //
16659 typedef void H_f; // character function //
16660 typedef void Z_f; // double complex function //
16661 typedef doublereal E_f; // real function with -R not specified //
16663 // undef any lower-case symbols that your C compiler predefines, e.g.: //
16666 // (No such symbols should be defined in a strict ANSI C compiler.
16667 We can avoid trouble with f2c-translated code by using
16668 gcc -ansi [-traditional].) //
16692 // Main program // MAIN__()
16694 // System generated locals //
16697 doublereal d__1, d__2;
16699 doublecomplex z__1, z__2, z__3;
16703 // Builtin functions //
16706 double pow_ri(), pow_di();
16710 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16711 asin(), atan(), atan2(), c_abs();
16712 void c_cos(), c_exp(), c_log(), r_cnjg();
16713 double cos(), cosh();
16714 void c_sin(), c_sqrt();
16715 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16716 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16717 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16718 logical l_ge(), l_gt(), l_le(), l_lt();
16722 // Local variables //
16723 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16724 fool_(), fooz_(), getem_();
16725 static char a1[10], a2[10];
16726 static complex c1, c2;
16727 static doublereal d1, d2;
16728 static integer i1, i2;
16729 static real r1, r2;
16732 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16740 d__1 = (doublereal) i1;
16741 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16751 c_div(&q__1, &c1, &c2);
16753 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16755 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16758 i__1 = pow_ii(&i1, &i2);
16760 r__1 = pow_ri(&r1, &i1);
16762 d__1 = pow_di(&d1, &i1);
16764 pow_ci(&q__1, &c1, &i1);
16766 d__1 = (doublereal) r1;
16767 d__2 = (doublereal) r2;
16768 r__1 = pow_dd(&d__1, &d__2);
16770 d__2 = (doublereal) r1;
16771 d__1 = pow_dd(&d__2, &d1);
16773 d__1 = pow_dd(&d1, &d2);
16775 d__2 = (doublereal) r1;
16776 d__1 = pow_dd(&d1, &d__2);
16778 z__2.r = c1.r, z__2.i = c1.i;
16779 z__3.r = c2.r, z__3.i = c2.i;
16780 pow_zz(&z__1, &z__2, &z__3);
16781 q__1.r = z__1.r, q__1.i = z__1.i;
16783 z__2.r = c1.r, z__2.i = c1.i;
16784 z__3.r = r1, z__3.i = 0.;
16785 pow_zz(&z__1, &z__2, &z__3);
16786 q__1.r = z__1.r, q__1.i = z__1.i;
16788 z__2.r = c1.r, z__2.i = c1.i;
16789 z__3.r = d1, z__3.i = 0.;
16790 pow_zz(&z__1, &z__2, &z__3);
16792 // FFEINTRIN_impABS //
16793 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
16795 // FFEINTRIN_impACOS //
16798 // FFEINTRIN_impAIMAG //
16799 r__1 = r_imag(&c1);
16801 // FFEINTRIN_impAINT //
16804 // FFEINTRIN_impALOG //
16807 // FFEINTRIN_impALOG10 //
16808 r__1 = r_lg10(&r1);
16810 // FFEINTRIN_impAMAX0 //
16811 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16813 // FFEINTRIN_impAMAX1 //
16814 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16816 // FFEINTRIN_impAMIN0 //
16817 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16819 // FFEINTRIN_impAMIN1 //
16820 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16822 // FFEINTRIN_impAMOD //
16823 r__1 = r_mod(&r1, &r2);
16825 // FFEINTRIN_impANINT //
16826 r__1 = r_nint(&r1);
16828 // FFEINTRIN_impASIN //
16831 // FFEINTRIN_impATAN //
16834 // FFEINTRIN_impATAN2 //
16835 r__1 = atan2(r1, r2);
16837 // FFEINTRIN_impCABS //
16840 // FFEINTRIN_impCCOS //
16843 // FFEINTRIN_impCEXP //
16846 // FFEINTRIN_impCHAR //
16847 *(unsigned char *)&ch__1[0] = i1;
16849 // FFEINTRIN_impCLOG //
16852 // FFEINTRIN_impCONJG //
16853 r_cnjg(&q__1, &c1);
16855 // FFEINTRIN_impCOS //
16858 // FFEINTRIN_impCOSH //
16861 // FFEINTRIN_impCSIN //
16864 // FFEINTRIN_impCSQRT //
16865 c_sqrt(&q__1, &c1);
16867 // FFEINTRIN_impDABS //
16868 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
16870 // FFEINTRIN_impDACOS //
16873 // FFEINTRIN_impDASIN //
16876 // FFEINTRIN_impDATAN //
16879 // FFEINTRIN_impDATAN2 //
16880 d__1 = atan2(d1, d2);
16882 // FFEINTRIN_impDCOS //
16885 // FFEINTRIN_impDCOSH //
16888 // FFEINTRIN_impDDIM //
16889 d__1 = d_dim(&d1, &d2);
16891 // FFEINTRIN_impDEXP //
16894 // FFEINTRIN_impDIM //
16895 r__1 = r_dim(&r1, &r2);
16897 // FFEINTRIN_impDINT //
16900 // FFEINTRIN_impDLOG //
16903 // FFEINTRIN_impDLOG10 //
16904 d__1 = d_lg10(&d1);
16906 // FFEINTRIN_impDMAX1 //
16907 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
16909 // FFEINTRIN_impDMIN1 //
16910 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
16912 // FFEINTRIN_impDMOD //
16913 d__1 = d_mod(&d1, &d2);
16915 // FFEINTRIN_impDNINT //
16916 d__1 = d_nint(&d1);
16918 // FFEINTRIN_impDPROD //
16919 d__1 = (doublereal) r1 * r2;
16921 // FFEINTRIN_impDSIGN //
16922 d__1 = d_sign(&d1, &d2);
16924 // FFEINTRIN_impDSIN //
16927 // FFEINTRIN_impDSINH //
16930 // FFEINTRIN_impDSQRT //
16933 // FFEINTRIN_impDTAN //
16936 // FFEINTRIN_impDTANH //
16939 // FFEINTRIN_impEXP //
16942 // FFEINTRIN_impIABS //
16943 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
16945 // FFEINTRIN_impICHAR //
16946 i__1 = *(unsigned char *)a1;
16948 // FFEINTRIN_impIDIM //
16949 i__1 = i_dim(&i1, &i2);
16951 // FFEINTRIN_impIDNINT //
16952 i__1 = i_dnnt(&d1);
16954 // FFEINTRIN_impINDEX //
16955 i__1 = i_indx(a1, a2, 10L, 10L);
16957 // FFEINTRIN_impISIGN //
16958 i__1 = i_sign(&i1, &i2);
16960 // FFEINTRIN_impLEN //
16961 i__1 = i_len(a1, 10L);
16963 // FFEINTRIN_impLGE //
16964 L__1 = l_ge(a1, a2, 10L, 10L);
16966 // FFEINTRIN_impLGT //
16967 L__1 = l_gt(a1, a2, 10L, 10L);
16969 // FFEINTRIN_impLLE //
16970 L__1 = l_le(a1, a2, 10L, 10L);
16972 // FFEINTRIN_impLLT //
16973 L__1 = l_lt(a1, a2, 10L, 10L);
16975 // FFEINTRIN_impMAX0 //
16976 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16978 // FFEINTRIN_impMAX1 //
16979 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16981 // FFEINTRIN_impMIN0 //
16982 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16984 // FFEINTRIN_impMIN1 //
16985 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16987 // FFEINTRIN_impMOD //
16990 // FFEINTRIN_impNINT //
16991 i__1 = i_nint(&r1);
16993 // FFEINTRIN_impSIGN //
16994 r__1 = r_sign(&r1, &r2);
16996 // FFEINTRIN_impSIN //
16999 // FFEINTRIN_impSINH //
17002 // FFEINTRIN_impSQRT //
17005 // FFEINTRIN_impTAN //
17008 // FFEINTRIN_impTANH //
17011 // FFEINTRIN_imp_CMPLX_C //
17014 q__1.r = r__1, q__1.i = r__2;
17016 // FFEINTRIN_imp_CMPLX_D //
17017 z__1.r = d1, z__1.i = d2;
17019 // FFEINTRIN_imp_CMPLX_I //
17022 q__1.r = r__1, q__1.i = r__2;
17024 // FFEINTRIN_imp_CMPLX_R //
17025 q__1.r = r1, q__1.i = r2;
17027 // FFEINTRIN_imp_DBLE_C //
17028 d__1 = (doublereal) c1.r;
17030 // FFEINTRIN_imp_DBLE_D //
17033 // FFEINTRIN_imp_DBLE_I //
17034 d__1 = (doublereal) i1;
17036 // FFEINTRIN_imp_DBLE_R //
17037 d__1 = (doublereal) r1;
17039 // FFEINTRIN_imp_INT_C //
17040 i__1 = (integer) c1.r;
17042 // FFEINTRIN_imp_INT_D //
17043 i__1 = (integer) d1;
17045 // FFEINTRIN_imp_INT_I //
17048 // FFEINTRIN_imp_INT_R //
17049 i__1 = (integer) r1;
17051 // FFEINTRIN_imp_REAL_C //
17054 // FFEINTRIN_imp_REAL_D //
17057 // FFEINTRIN_imp_REAL_I //
17060 // FFEINTRIN_imp_REAL_R //
17064 // FFEINTRIN_imp_INT_D: //
17066 // FFEINTRIN_specIDINT //
17067 i__1 = (integer) d1;
17070 // FFEINTRIN_imp_INT_R: //
17072 // FFEINTRIN_specIFIX //
17073 i__1 = (integer) r1;
17075 // FFEINTRIN_specINT //
17076 i__1 = (integer) r1;
17079 // FFEINTRIN_imp_REAL_D: //
17081 // FFEINTRIN_specSNGL //
17085 // FFEINTRIN_imp_REAL_I: //
17087 // FFEINTRIN_specFLOAT //
17090 // FFEINTRIN_specREAL //
17096 -------- (end output file from f2c)