1 /* com.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
4 Contributed by James Craig Burley.
6 This file is part of GNU Fortran.
8 GNU Fortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU Fortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Fortran; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 Contains compiler-specific functions.
32 /* Understanding this module means understanding the interface between
33 the g77 front end and the gcc back end (or, perhaps, some other
34 back end). In here are the functions called by the front end proper
35 to notify whatever back end is in place about certain things, and
36 also the back-end-specific functions. It's a bear to deal with, so
37 lately I've been trying to simplify things, especially with regard
38 to the gcc-back-end-specific stuff.
40 Building expressions generally seems quite easy, but building decls
41 has been challenging and is undergoing revision. gcc has several
44 TYPE_DECL -- a type (int, float, struct, function, etc.)
45 CONST_DECL -- a constant of some type other than function
46 LABEL_DECL -- a variable or a constant?
47 PARM_DECL -- an argument to a function (a variable that is a dummy)
48 RESULT_DECL -- the return value of a function (a variable)
49 VAR_DECL -- other variable (can hold a ptr-to-function, struct, int, etc.)
50 FUNCTION_DECL -- a function (either the actual function or an extern ref)
51 FIELD_DECL -- a field in a struct or union (goes into types)
53 g77 has a set of functions that somewhat parallels the gcc front end
54 when it comes to building decls:
56 Internal Function (one we define, not just declare as extern):
57 if (is_nested) push_f_function_context ();
58 start_function (get_identifier ("function_name"), function_type,
59 is_nested, is_public);
60 // for each arg, build PARM_DECL and call push_parm_decl (decl) with it;
61 store_parm_decls (is_main_program);
62 ffecom_start_compstmt ();
63 // for stmts and decls inside function, do appropriate things;
64 ffecom_end_compstmt ();
65 finish_function (is_nested);
66 if (is_nested) pop_f_function_context ();
71 // fill in external, public, static, &c for decl, and
72 // set DECL_INITIAL to error_mark_node if going to initialize
73 // set is_top_level TRUE only if not at top level and decl
74 // must go in top level (i.e. not within current function decl context)
75 d = start_decl (decl, is_top_level);
76 init = ...; // if have initializer
77 finish_decl (d, init, is_top_level);
89 #include "output.h" /* Must follow tree.h so TREE_CODE is defined! */
92 #include "diagnostic.h"
94 #include "langhooks.h"
95 #include "langhooks-def.h"
98 /* VMS-specific definitions */
101 #define O_RDONLY 0 /* Open arg for Read/Only */
102 #define O_WRONLY 1 /* Open arg for Write/Only */
103 #define read(fd,buf,size) VMS_read (fd,buf,size)
104 #define write(fd,buf,size) VMS_write (fd,buf,size)
105 #define open(fname,mode,prot) VMS_open (fname,mode,prot)
106 #define fopen(fname,mode) VMS_fopen (fname,mode)
107 #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
108 #define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
109 #define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
110 static int VMS_fstat (), VMS_stat ();
111 static char * VMS_strncat ();
112 static int VMS_read ();
113 static int VMS_write ();
114 static int VMS_open ();
115 static FILE * VMS_fopen ();
116 static FILE * VMS_freopen ();
117 static void hack_vms_include_specification ();
118 typedef struct { unsigned :16, :16, :16; } vms_ino_t
;
119 #define ino_t vms_ino_t
120 #define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
123 #define FFECOM_DETERMINE_TYPES 1 /* for com.h */
139 #include "function.h"
141 /* Externals defined here. */
143 /* Stream for reading from the input file. */
146 /* These definitions parallel those in c-decl.c so that code from that
147 module can be used pretty much as is. Much of these defs aren't
148 otherwise used, i.e. by g77 code per se, except some of them are used
149 to build some of them that are. The ones that are global (i.e. not
150 "static") are those that ste.c and such might use (directly
151 or by using com macros that reference them in their definitions). */
153 tree string_type_node
;
155 /* The rest of these are inventions for g77, though there might be
156 similar things in the C front end. As they are found, these
157 inventions should be renamed to be canonical. Note that only
158 the ones currently required to be global are so. */
160 static GTY(()) tree ffecom_tree_fun_type_void
;
162 tree ffecom_integer_type_node
; /* Abbrev for _tree_type[blah][blah]. */
163 tree ffecom_integer_zero_node
; /* Like *_*_* with g77's integer type. */
164 tree ffecom_integer_one_node
; /* " */
165 tree ffecom_tree_type
[FFEINFO_basictype
][FFEINFO_kindtype
];
167 /* _fun_type things are the f2c-specific versions. For -fno-f2c,
168 just use build_function_type and build_pointer_type on the
169 appropriate _tree_type array element. */
171 static GTY(()) tree ffecom_tree_fun_type
[FFEINFO_basictype
][FFEINFO_kindtype
];
173 ffecom_tree_ptr_to_fun_type
[FFEINFO_basictype
][FFEINFO_kindtype
];
174 static GTY(()) tree ffecom_tree_subr_type
;
175 static GTY(()) tree ffecom_tree_ptr_to_subr_type
;
176 static GTY(()) tree ffecom_tree_blockdata_type
;
178 static GTY(()) tree ffecom_tree_xargc_
;
180 ffecomSymbol ffecom_symbol_null_
189 ffeinfoKindtype ffecom_pointer_kind_
= FFEINFO_basictypeNONE
;
190 ffeinfoKindtype ffecom_label_kind_
= FFEINFO_basictypeNONE
;
192 int ffecom_f2c_typecode_
[FFEINFO_basictype
][FFEINFO_kindtype
];
193 tree ffecom_f2c_integer_type_node
;
194 static GTY(()) tree ffecom_f2c_ptr_to_integer_type_node
;
195 tree ffecom_f2c_address_type_node
;
196 tree ffecom_f2c_real_type_node
;
197 static GTY(()) tree ffecom_f2c_ptr_to_real_type_node
;
198 tree ffecom_f2c_doublereal_type_node
;
199 tree ffecom_f2c_complex_type_node
;
200 tree ffecom_f2c_doublecomplex_type_node
;
201 tree ffecom_f2c_longint_type_node
;
202 tree ffecom_f2c_logical_type_node
;
203 tree ffecom_f2c_flag_type_node
;
204 tree ffecom_f2c_ftnlen_type_node
;
205 tree ffecom_f2c_ftnlen_zero_node
;
206 tree ffecom_f2c_ftnlen_one_node
;
207 tree ffecom_f2c_ftnlen_two_node
;
208 tree ffecom_f2c_ptr_to_ftnlen_type_node
;
209 tree ffecom_f2c_ftnint_type_node
;
210 tree ffecom_f2c_ptr_to_ftnint_type_node
;
212 /* Simple definitions and enumerations. */
214 #ifndef FFECOM_sizeMAXSTACKITEM
215 #define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
216 larger than this # bytes
217 off stack if possible. */
220 /* For systems that have large enough stacks, they should define
221 this to 0, and here, for ease of use later on, we just undefine
224 #if FFECOM_sizeMAXSTACKITEM == 0
225 #undef FFECOM_sizeMAXSTACKITEM
231 FFECOM_rttypeVOIDSTAR_
, /* C's `void *' type. */
232 FFECOM_rttypeFTNINT_
, /* f2c's `ftnint' type. */
233 FFECOM_rttypeINTEGER_
, /* f2c's `integer' type. */
234 FFECOM_rttypeLONGINT_
, /* f2c's `longint' type. */
235 FFECOM_rttypeLOGICAL_
, /* f2c's `logical' type. */
236 FFECOM_rttypeREAL_F2C_
, /* f2c's `real' returned as `double'. */
237 FFECOM_rttypeREAL_GNU_
, /* `real' returned as such. */
238 FFECOM_rttypeCOMPLEX_F2C_
, /* f2c's `complex' returned via 1st arg. */
239 FFECOM_rttypeCOMPLEX_GNU_
, /* f2c's `complex' returned directly. */
240 FFECOM_rttypeDOUBLE_
, /* C's `double' type. */
241 FFECOM_rttypeDOUBLEREAL_
, /* f2c's `doublereal' type. */
242 FFECOM_rttypeDBLCMPLX_F2C_
, /* f2c's `doublecomplex' returned via 1st arg. */
243 FFECOM_rttypeDBLCMPLX_GNU_
, /* f2c's `doublecomplex' returned directly. */
244 FFECOM_rttypeCHARACTER_
, /* f2c `char *'/`ftnlen' pair. */
248 /* Internal typedefs. */
250 typedef struct _ffecom_concat_list_ ffecomConcatList_
;
252 /* Private include files. */
255 /* Internal structure definitions. */
257 struct _ffecom_concat_list_
262 ffetargetCharacterSize minlen
;
263 ffetargetCharacterSize maxlen
;
266 /* Static functions (internal). */
268 static tree
ffe_type_for_mode (enum machine_mode
, int);
269 static tree
ffe_type_for_size (unsigned int, int);
270 static tree
ffe_unsigned_type (tree
);
271 static tree
ffe_signed_type (tree
);
272 static tree
ffe_signed_or_unsigned_type (int, tree
);
273 static bool ffe_mark_addressable (tree
);
274 static tree
ffe_truthvalue_conversion (tree
);
275 static void ffecom_init_decl_processing (void);
276 static tree
ffecom_arglist_expr_ (const char *argstring
, ffebld args
);
277 static tree
ffecom_widest_expr_type_ (ffebld list
);
278 static bool ffecom_overlap_ (tree dest_decl
, tree dest_offset
,
279 tree dest_size
, tree source_tree
,
280 ffebld source
, bool scalar_arg
);
281 static bool ffecom_args_overlapping_ (tree dest_tree
, ffebld dest
,
282 tree args
, tree callee_commons
,
284 static tree
ffecom_build_f2c_string_ (int i
, const char *s
);
285 static tree
ffecom_call_ (tree fn
, ffeinfoKindtype kt
,
286 bool is_f2c_complex
, tree type
,
287 tree args
, tree dest_tree
,
288 ffebld dest
, bool *dest_used
,
289 tree callee_commons
, bool scalar_args
, tree hook
);
290 static tree
ffecom_call_binop_ (tree fn
, ffeinfoKindtype kt
,
291 bool is_f2c_complex
, tree type
,
292 ffebld left
, ffebld right
,
293 tree dest_tree
, ffebld dest
,
294 bool *dest_used
, tree callee_commons
,
295 bool scalar_args
, bool ref
, tree hook
);
296 static void ffecom_char_args_x_ (tree
*xitem
, tree
*length
,
297 ffebld expr
, bool with_null
);
298 static tree
ffecom_check_size_overflow_ (ffesymbol s
, tree type
, bool dummy
);
299 static tree
ffecom_char_enhance_arg_ (tree
*xtype
, ffesymbol s
);
300 static ffecomConcatList_
301 ffecom_concat_list_gather_ (ffecomConcatList_ catlist
,
303 ffetargetCharacterSize max
);
304 static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist
);
305 static ffecomConcatList_
ffecom_concat_list_new_ (ffebld expr
,
306 ffetargetCharacterSize max
);
307 static void ffecom_debug_kludge_ (tree aggr
, const char *aggr_type
,
308 ffesymbol member
, tree member_type
,
309 ffetargetOffset offset
);
310 static void ffecom_do_entry_ (ffesymbol fn
, int entrynum
);
311 static tree
ffecom_expr_ (ffebld expr
, tree dest_tree
, ffebld dest
,
312 bool *dest_used
, bool assignp
, bool widenp
);
313 static tree
ffecom_expr_intrinsic_ (ffebld expr
, tree dest_tree
,
314 ffebld dest
, bool *dest_used
);
315 static tree
ffecom_expr_power_integer_ (ffebld expr
);
316 static void ffecom_expr_transform_ (ffebld expr
);
317 static void ffecom_f2c_make_type_ (tree
*type
, int tcode
, const char *name
);
318 static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt
, int size
,
320 static ffeglobal
ffecom_finish_global_ (ffeglobal global
);
321 static ffesymbol
ffecom_finish_symbol_transform_ (ffesymbol s
);
322 static tree
ffecom_get_appended_identifier_ (char us
, const char *text
);
323 static tree
ffecom_get_external_identifier_ (ffesymbol s
);
324 static tree
ffecom_get_identifier_ (const char *text
);
325 static tree
ffecom_gen_sfuncdef_ (ffesymbol s
,
328 static const char *ffecom_gfrt_args_ (ffecomGfrt ix
);
329 static tree
ffecom_gfrt_tree_ (ffecomGfrt ix
);
330 static tree
ffecom_init_zero_ (tree decl
);
331 static tree
ffecom_intrinsic_ichar_ (tree tree_type
, ffebld arg
,
333 static tree
ffecom_intrinsic_len_ (ffebld expr
);
334 static void ffecom_let_char_ (tree dest_tree
,
336 ffetargetCharacterSize dest_size
,
338 static void ffecom_make_gfrt_ (ffecomGfrt ix
);
339 static void ffecom_member_phase1_ (ffestorag mst
, ffestorag st
);
340 static void ffecom_member_phase2_ (ffestorag mst
, ffestorag st
);
341 static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size
,
343 static void ffecom_push_dummy_decls_ (ffebld dumlist
,
345 static void ffecom_start_progunit_ (void);
346 static ffesymbol
ffecom_sym_transform_ (ffesymbol s
);
347 static ffesymbol
ffecom_sym_transform_assign_ (ffesymbol s
);
348 static void ffecom_transform_common_ (ffesymbol s
);
349 static void ffecom_transform_equiv_ (ffestorag st
);
350 static tree
ffecom_transform_namelist_ (ffesymbol s
);
351 static void ffecom_tree_canonize_ptr_ (tree
*decl
, tree
*offset
,
353 static void ffecom_tree_canonize_ref_ (tree
*decl
, tree
*offset
,
354 tree
*size
, tree tree
);
355 static tree
ffecom_tree_divide_ (tree tree_type
, tree left
, tree right
,
356 tree dest_tree
, ffebld dest
,
357 bool *dest_used
, tree hook
);
358 static tree
ffecom_type_localvar_ (ffesymbol s
,
361 static tree
ffecom_type_namelist_ (void);
362 static tree
ffecom_type_vardesc_ (void);
363 static tree
ffecom_vardesc_ (ffebld expr
);
364 static tree
ffecom_vardesc_array_ (ffesymbol s
);
365 static tree
ffecom_vardesc_dims_ (ffesymbol s
);
366 static tree
ffecom_convert_narrow_ (tree type
, tree expr
);
367 static tree
ffecom_convert_widen_ (tree type
, tree expr
);
369 /* These are static functions that parallel those found in the C front
370 end and thus have the same names. */
372 static tree
bison_rule_compstmt_ (void);
373 static void bison_rule_pushlevel_ (void);
374 static void delete_block (tree block
);
375 static int duplicate_decls (tree newdecl
, tree olddecl
);
376 static void finish_decl (tree decl
, tree init
, bool is_top_level
);
377 static void finish_function (int nested
);
378 static const char *ffe_printable_name (tree decl
, int v
);
379 static void ffe_print_error_function (diagnostic_context
*, const char *);
380 static tree
lookup_name_current_level (tree name
);
381 static struct f_binding_level
*make_binding_level (void);
382 static void pop_f_function_context (void);
383 static void push_f_function_context (void);
384 static void push_parm_decl (tree parm
);
385 static tree
pushdecl_top_level (tree decl
);
386 static int kept_level_p (void);
387 static tree
storedecls (tree decls
);
388 static void store_parm_decls (int is_main_program
);
389 static tree
start_decl (tree decl
, bool is_top_level
);
390 static void start_function (tree name
, tree type
, int nested
, int public);
391 static void ffecom_file_ (const char *name
);
392 static void ffecom_close_include_ (FILE *f
);
393 static FILE *ffecom_open_include_ (char *name
, ffewhereLine l
,
396 /* Static objects accessed by functions in this module. */
398 static ffesymbol ffecom_primary_entry_
= NULL
;
399 static ffesymbol ffecom_nested_entry_
= NULL
;
400 static ffeinfoKind ffecom_primary_entry_kind_
;
401 static bool ffecom_primary_entry_is_proc_
;
402 static GTY(()) tree ffecom_outer_function_decl_
;
403 static GTY(()) tree ffecom_previous_function_decl_
;
404 static GTY(()) tree ffecom_which_entrypoint_decl_
;
405 static GTY(()) tree ffecom_float_zero_
;
406 static GTY(()) tree ffecom_float_half_
;
407 static GTY(()) tree ffecom_double_zero_
;
408 static GTY(()) tree ffecom_double_half_
;
409 static GTY(()) tree ffecom_func_result_
;/* For functions. */
410 static GTY(()) tree ffecom_func_length_
;/* For CHARACTER fns. */
411 static ffebld ffecom_list_blockdata_
;
412 static ffebld ffecom_list_common_
;
413 static ffebld ffecom_master_arglist_
;
414 static ffeinfoBasictype ffecom_master_bt_
;
415 static ffeinfoKindtype ffecom_master_kt_
;
416 static ffetargetCharacterSize ffecom_master_size_
;
417 static int ffecom_num_fns_
= 0;
418 static int ffecom_num_entrypoints_
= 0;
419 static bool ffecom_is_altreturning_
= FALSE
;
420 static GTY(()) tree ffecom_multi_type_node_
;
421 static GTY(()) tree ffecom_multi_retval_
;
423 ffecom_multi_fields_
[FFEINFO_basictype
][FFEINFO_kindtype
];
424 static bool ffecom_member_namelisted_
; /* _member_phase1_ namelisted? */
425 static bool ffecom_doing_entry_
= FALSE
;
426 static bool ffecom_transform_only_dummies_
= FALSE
;
427 static int ffecom_typesize_pointer_
;
428 static int ffecom_typesize_integer1_
;
430 /* Holds pointer-to-function expressions. */
432 static GTY(()) tree ffecom_gfrt_
[FFECOM_gfrt
];
434 /* Holds the external names of the functions. */
436 static const char *const ffecom_gfrt_name_
[FFECOM_gfrt
]
439 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NAME,
440 #include "com-rt.def"
444 /* Whether the function returns. */
446 static const bool ffecom_gfrt_volatile_
[FFECOM_gfrt
]
449 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) VOLATILE,
450 #include "com-rt.def"
454 /* Whether the function returns type complex. */
456 static const bool ffecom_gfrt_complex_
[FFECOM_gfrt
]
459 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) COMPLEX,
460 #include "com-rt.def"
464 /* Whether the function is const
465 (i.e., has no side effects and only depends on its arguments). */
467 static const bool ffecom_gfrt_const_
[FFECOM_gfrt
]
470 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) CONST,
471 #include "com-rt.def"
475 /* Type code for the function return value. */
477 static const ffecomRttype_ ffecom_gfrt_type_
[FFECOM_gfrt
]
480 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) TYPE,
481 #include "com-rt.def"
485 /* String of codes for the function's arguments. */
487 static const char *const ffecom_gfrt_argstring_
[FFECOM_gfrt
]
490 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) ARGS,
491 #include "com-rt.def"
495 /* Internal macros. */
497 /* We let tm.h override the types used here, to handle trivial differences
498 such as the choice of unsigned int or long unsigned int for size_t.
499 When machines start needing nontrivial differences in the size type,
500 it would be best to do something here to figure out automatically
501 from other information what type to use. */
504 #define SIZE_TYPE "long unsigned int"
507 #define ffecom_concat_list_count_(catlist) ((catlist).count)
508 #define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
509 #define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
510 #define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
512 #define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
513 #define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
515 /* For each binding contour we allocate a binding_level structure
516 * which records the names defined in that contour.
519 * 1) one for each function definition,
520 * where internal declarations of the parameters appear.
522 * The current meaning of a name can be found by searching the levels from
523 * the current one out to the global one.
526 /* Note that the information in the `names' component of the global contour
527 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
529 struct f_binding_level
GTY(())
531 /* A chain of _DECL nodes for all variables, constants, functions,
532 and typedef types. These are in the reverse of the order supplied.
536 /* For each level (except not the global one),
537 a chain of BLOCK nodes for all the levels
538 that were entered and exited one level down. */
541 /* The BLOCK node for this level, if one has been preallocated.
542 If 0, the BLOCK is allocated (if needed) when the level is popped. */
545 /* The binding level which this one is contained in (inherits from). */
546 struct f_binding_level
*level_chain
;
548 /* 0: no ffecom_prepare_* functions called at this level yet;
549 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
550 2: ffecom_prepare_end called. */
554 #define NULL_BINDING_LEVEL (struct f_binding_level *) NULL
556 /* The binding level currently in effect. */
558 static GTY(()) struct f_binding_level
*current_binding_level
;
560 /* A chain of binding_level structures awaiting reuse. */
562 static GTY((deletable
)) struct f_binding_level
*free_binding_level
;
564 /* The outermost binding level, for names of file scope.
565 This is created when the compiler is started and exists
566 through the entire run. */
568 static struct f_binding_level
*global_binding_level
;
570 /* Binding level structures are initialized by copying this one. */
572 static const struct f_binding_level clear_binding_level
574 {NULL
, NULL
, NULL
, NULL_BINDING_LEVEL
, 0};
576 /* Language-dependent contents of an identifier. */
578 struct lang_identifier
GTY(())
580 struct tree_identifier common
;
587 /* Macros for access to language-specific slots in an identifier. */
588 /* Each of these slots contains a DECL node or null. */
590 /* This represents the value which the identifier has in the
591 file-scope namespace. */
592 #define IDENTIFIER_GLOBAL_VALUE(NODE) \
593 (((struct lang_identifier *)(NODE))->global_value)
594 /* This represents the value which the identifier has in the current
596 #define IDENTIFIER_LOCAL_VALUE(NODE) \
597 (((struct lang_identifier *)(NODE))->local_value)
598 /* This represents the value which the identifier has as a label in
599 the current label scope. */
600 #define IDENTIFIER_LABEL_VALUE(NODE) \
601 (((struct lang_identifier *)(NODE))->label_value)
602 /* This is nonzero if the identifier was "made up" by g77 code. */
603 #define IDENTIFIER_INVENTED(NODE) \
604 (((struct lang_identifier *)(NODE))->invented)
606 /* The resulting tree type. */
608 GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
609 chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
611 union tree_node
GTY ((tag ("0"),
612 desc ("tree_node_structure (&%h)")))
614 struct lang_identifier
GTY ((tag ("1"))) identifier
;
617 /* Fortran doesn't use either of these. */
618 struct lang_decl
GTY(())
621 struct lang_type
GTY(())
625 /* In identifiers, C uses the following fields in a special way:
626 TREE_PUBLIC to record that there was a previous local extern decl.
627 TREE_USED to record that such a decl was used.
628 TREE_ADDRESSABLE to record that the address of such a decl was used. */
630 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
631 that have names. Here so we can clear out their names' definitions
632 at the end of the function. */
634 static GTY(()) tree named_labels
;
636 /* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
638 static GTY(()) tree shadowed_labels
;
640 /* Return the subscript expression, modified to do range-checking.
642 `array' is the array type to be checked against.
643 `element' is the subscript expression to check.
644 `dim' is the dimension number (starting at 0).
645 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
646 `item' is the array decl or NULL_TREE.
650 ffecom_subscript_check_ (tree array
, tree element
, int dim
, int total_dims
,
651 const char *array_name
, tree item
)
653 tree low
= TYPE_MIN_VALUE (TYPE_DOMAIN (array
));
654 tree high
= TYPE_MAX_VALUE (TYPE_DOMAIN (array
));
659 if (element
== error_mark_node
)
662 if (TREE_TYPE (low
) != TREE_TYPE (element
))
664 if (TYPE_PRECISION (TREE_TYPE (low
))
665 > TYPE_PRECISION (TREE_TYPE (element
)))
666 element
= convert (TREE_TYPE (low
), element
);
669 low
= convert (TREE_TYPE (element
), low
);
671 high
= convert (TREE_TYPE (element
), high
);
675 element
= ffecom_save_tree (element
);
678 /* Special handling for substring range checks. Fortran allows the
679 end subscript < begin subscript, which means that expressions like
680 string(1:0) are valid (and yield a null string). In view of this,
681 enforce two simpler conditions:
682 1) element<=high for end-substring;
683 2) element>=low for start-substring.
684 Run-time character movement will enforce remaining conditions.
686 More complicated checks would be better, but present structure only
687 provides one index element at a time, so it is not possible to
688 enforce a check of both i and j in string(i:j). If it were, the
689 complete set of rules would read,
690 if ( ((j<i) && ((low<=i<=high) || (low<=j<=high))) ||
691 ((low<=i<=high) && (low<=j<=high)) )
697 cond
= ffecom_2 (LE_EXPR
, integer_type_node
, element
, high
);
699 cond
= ffecom_2 (LE_EXPR
, integer_type_node
, low
, element
);
703 /* Array reference substring range checking. */
705 cond
= ffecom_2 (LE_EXPR
, integer_type_node
,
710 cond
= ffecom_2 (TRUTH_ANDIF_EXPR
, integer_type_node
,
712 ffecom_2 (LE_EXPR
, integer_type_node
,
718 /* If the array index is safe at compile-time, return element. */
719 if (integer_nonzerop (cond
))
734 var
= concat (array_name
, "[", (dim
? "end" : "start"),
735 "-substring]", NULL
);
736 len
= strlen (var
) + 1;
737 arg1
= build_string (len
, var
);
742 len
= strlen (array_name
) + 1;
743 arg1
= build_string (len
, array_name
);
747 var
= xmalloc (strlen (array_name
) + 40);
748 sprintf (var
, "%s[subscript-%d-of-%d]",
750 dim
+ 1, total_dims
);
751 len
= strlen (var
) + 1;
752 arg1
= build_string (len
, var
);
758 = build_type_variant (build_array_type (char_type_node
,
762 build_int_2 (len
, 0))),
764 TREE_CONSTANT (arg1
) = 1;
765 TREE_STATIC (arg1
) = 1;
766 arg1
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (arg1
)),
769 /* s_rnge adds one to the element to print it, so bias against
770 that -- want to print a faithful *subscript* value. */
771 arg2
= convert (ffecom_f2c_ftnint_type_node
,
772 ffecom_2 (MINUS_EXPR
,
775 convert (TREE_TYPE (element
),
778 proc
= concat (input_filename
, "/",
779 IDENTIFIER_POINTER (DECL_NAME (current_function_decl
)),
781 len
= strlen (proc
) + 1;
782 arg3
= build_string (len
, proc
);
787 = build_type_variant (build_array_type (char_type_node
,
791 build_int_2 (len
, 0))),
793 TREE_CONSTANT (arg3
) = 1;
794 TREE_STATIC (arg3
) = 1;
795 arg3
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (arg3
)),
798 arg4
= convert (ffecom_f2c_ftnint_type_node
,
799 build_int_2 (input_line
, 0));
801 arg1
= build_tree_list (NULL_TREE
, arg1
);
802 arg2
= build_tree_list (NULL_TREE
, arg2
);
803 arg3
= build_tree_list (NULL_TREE
, arg3
);
804 arg4
= build_tree_list (NULL_TREE
, arg4
);
805 TREE_CHAIN (arg3
) = arg4
;
806 TREE_CHAIN (arg2
) = arg3
;
807 TREE_CHAIN (arg1
) = arg2
;
811 die
= ffecom_call_gfrt (FFECOM_gfrtRANGE
,
813 TREE_SIDE_EFFECTS (die
) = 1;
814 die
= convert (void_type_node
, die
);
816 if (integer_zerop (cond
) && item
)
817 ffe_mark_addressable (item
);
819 return ffecom_3 (COND_EXPR
, TREE_TYPE (element
), cond
, element
, die
);
822 /* Return the computed element of an array reference.
824 `item' is NULL_TREE, or the transformed pointer to the array.
825 `expr' is the original opARRAYREF expression, which is transformed
826 if `item' is NULL_TREE.
827 `want_ptr' is nonzero if a pointer to the element, instead of
828 the element itself, is to be returned. */
831 ffecom_arrayref_ (tree item
, ffebld expr
, int want_ptr
)
833 ffebld dims
[FFECOM_dimensionsMAX
];
836 int flatten
= ffe_is_flatten_arrays ();
842 const char *array_name
;
846 if (ffebld_op (ffebld_left (expr
)) == FFEBLD_opSYMTER
)
847 array_name
= ffesymbol_text (ffebld_symter (ffebld_left (expr
)));
849 array_name
= "[expr?]";
851 /* Build up ARRAY_REFs in reverse order (since we're column major
852 here in Fortran land). */
854 for (i
= 0, list
= ffebld_right (expr
);
856 ++i
, list
= ffebld_trail (list
))
858 dims
[i
] = ffebld_head (list
);
859 type
= ffeinfo_type (ffebld_basictype (dims
[i
]),
860 ffebld_kindtype (dims
[i
]));
862 && ffecom_typesize_pointer_
> ffecom_typesize_integer1_
863 && ffetype_size (type
) > ffecom_typesize_integer1_
)
864 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
865 pointers and 32-bit integers. Do the full 64-bit pointer
866 arithmetic, for codes using arrays for nonstandard heap-like
873 need_ptr
= want_ptr
|| flatten
;
878 item
= ffecom_ptr_to_expr (ffebld_left (expr
));
880 item
= ffecom_expr (ffebld_left (expr
));
882 if (item
== error_mark_node
)
885 if (ffeinfo_where (ffebld_info (expr
)) == FFEINFO_whereFLEETING
886 && ! ffe_mark_addressable (item
))
887 return error_mark_node
;
890 if (item
== error_mark_node
)
897 for (--i
, array
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item
)));
899 --i
, array
= TYPE_MAIN_VARIANT (TREE_TYPE (array
)))
901 min
= TYPE_MIN_VALUE (TYPE_DOMAIN (array
));
902 element
= ffecom_expr_ (dims
[i
], NULL
, NULL
, NULL
, FALSE
, TRUE
);
903 if (flag_bounds_check
)
904 element
= ffecom_subscript_check_ (array
, element
, i
, total_dims
,
906 if (element
== error_mark_node
)
909 /* Widen integral arithmetic as desired while preserving
911 tree_type
= TREE_TYPE (element
);
912 tree_type_x
= tree_type
;
914 && GET_MODE_CLASS (TYPE_MODE (tree_type
)) == MODE_INT
915 && TYPE_PRECISION (tree_type
) < TYPE_PRECISION (sizetype
))
916 tree_type_x
= (TYPE_UNSIGNED (tree_type
) ? usizetype
: ssizetype
);
918 if (TREE_TYPE (min
) != tree_type_x
)
919 min
= convert (tree_type_x
, min
);
920 if (TREE_TYPE (element
) != tree_type_x
)
921 element
= convert (tree_type_x
, element
);
923 item
= ffecom_2 (PLUS_EXPR
,
924 build_pointer_type (TREE_TYPE (array
)),
926 size_binop (MULT_EXPR
,
927 size_in_bytes (TREE_TYPE (array
)),
929 fold (build (MINUS_EXPR
,
935 item
= ffecom_1 (INDIRECT_REF
,
936 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item
))),
946 array
= TYPE_MAIN_VARIANT (TREE_TYPE (item
));
948 element
= ffecom_expr_ (dims
[i
], NULL
, NULL
, NULL
, FALSE
, TRUE
);
949 if (flag_bounds_check
)
950 element
= ffecom_subscript_check_ (array
, element
, i
, total_dims
,
952 if (element
== error_mark_node
)
955 /* Widen integral arithmetic as desired while preserving
957 tree_type
= TREE_TYPE (element
);
958 tree_type_x
= tree_type
;
960 && GET_MODE_CLASS (TYPE_MODE (tree_type
)) == MODE_INT
961 && TYPE_PRECISION (tree_type
) < TYPE_PRECISION (sizetype
))
962 tree_type_x
= (TYPE_UNSIGNED (tree_type
) ? usizetype
: ssizetype
);
964 element
= convert (tree_type_x
, element
);
966 item
= ffecom_2 (ARRAY_REF
,
967 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item
))),
976 /* This is like gcc's stabilize_reference -- in fact, most of the code
977 comes from that -- but it handles the situation where the reference
978 is going to have its subparts picked at, and it shouldn't change
979 (or trigger extra invocations of functions in the subtrees) due to
980 this. save_expr is a bit overzealous, because we don't need the
981 entire thing calculated and saved like a temp. So, for DECLs, no
982 change is needed, because these are stable aggregates, and ARRAY_REF
983 and such might well be stable too, but for things like calculations,
984 we do need to calculate a snapshot of a value before picking at it. */
987 ffecom_stabilize_aggregate_ (tree ref
)
990 enum tree_code code
= TREE_CODE (ref
);
997 /* No action is needed in this case. */
1003 case FIX_TRUNC_EXPR
:
1004 case FIX_FLOOR_EXPR
:
1005 case FIX_ROUND_EXPR
:
1007 result
= build_nt (code
, stabilize_reference (TREE_OPERAND (ref
, 0)));
1011 result
= build_nt (INDIRECT_REF
,
1012 stabilize_reference_1 (TREE_OPERAND (ref
, 0)));
1016 result
= build_nt (COMPONENT_REF
,
1017 stabilize_reference (TREE_OPERAND (ref
, 0)),
1018 TREE_OPERAND (ref
, 1));
1022 result
= build_nt (BIT_FIELD_REF
,
1023 stabilize_reference (TREE_OPERAND (ref
, 0)),
1024 stabilize_reference_1 (TREE_OPERAND (ref
, 1)),
1025 stabilize_reference_1 (TREE_OPERAND (ref
, 2)));
1029 result
= build_nt (ARRAY_REF
,
1030 stabilize_reference (TREE_OPERAND (ref
, 0)),
1031 stabilize_reference_1 (TREE_OPERAND (ref
, 1)));
1035 result
= build_nt (COMPOUND_EXPR
,
1036 stabilize_reference_1 (TREE_OPERAND (ref
, 0)),
1037 stabilize_reference (TREE_OPERAND (ref
, 1)));
1045 return save_expr (ref
);
1048 return error_mark_node
;
1051 TREE_TYPE (result
) = TREE_TYPE (ref
);
1052 TREE_READONLY (result
) = TREE_READONLY (ref
);
1053 TREE_SIDE_EFFECTS (result
) = TREE_SIDE_EFFECTS (ref
);
1054 TREE_THIS_VOLATILE (result
) = TREE_THIS_VOLATILE (ref
);
1059 /* A rip-off of gcc's convert.c convert_to_complex function,
1060 reworked to handle complex implemented as C structures
1061 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1064 ffecom_convert_to_complex_ (tree type
, tree expr
)
1066 register enum tree_code form
= TREE_CODE (TREE_TYPE (expr
));
1069 assert (TREE_CODE (type
) == RECORD_TYPE
);
1071 subtype
= TREE_TYPE (TYPE_FIELDS (type
));
1073 if (form
== REAL_TYPE
|| form
== INTEGER_TYPE
|| form
== ENUMERAL_TYPE
)
1075 expr
= convert (subtype
, expr
);
1076 return ffecom_2 (COMPLEX_EXPR
, type
, expr
,
1077 convert (subtype
, integer_zero_node
));
1080 if (form
== RECORD_TYPE
)
1082 tree elt_type
= TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr
)));
1083 if (TYPE_MAIN_VARIANT (elt_type
) == TYPE_MAIN_VARIANT (subtype
))
1087 expr
= save_expr (expr
);
1088 return ffecom_2 (COMPLEX_EXPR
,
1091 ffecom_1 (REALPART_EXPR
,
1092 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr
))),
1095 ffecom_1 (IMAGPART_EXPR
,
1096 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr
))),
1101 if (form
== POINTER_TYPE
|| form
== REFERENCE_TYPE
)
1102 error ("pointer value used where a complex was expected");
1104 error ("aggregate value used where a complex was expected");
1106 return ffecom_2 (COMPLEX_EXPR
, type
,
1107 convert (subtype
, integer_zero_node
),
1108 convert (subtype
, integer_zero_node
));
1111 /* Like gcc's convert(), but crashes if widening might happen. */
1114 ffecom_convert_narrow_ (tree type
, tree expr
)
1116 register tree e
= expr
;
1117 register enum tree_code code
= TREE_CODE (type
);
1119 if (type
== TREE_TYPE (e
)
1120 || TREE_CODE (e
) == ERROR_MARK
)
1122 if (TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (TREE_TYPE (e
)))
1123 return fold (build1 (NOP_EXPR
, type
, e
));
1124 if (TREE_CODE (TREE_TYPE (e
)) == ERROR_MARK
1125 || code
== ERROR_MARK
)
1126 return error_mark_node
;
1127 if (TREE_CODE (TREE_TYPE (e
)) == VOID_TYPE
)
1129 assert ("void value not ignored as it ought to be" == NULL
);
1130 return error_mark_node
;
1132 assert (code
!= VOID_TYPE
);
1133 if ((code
!= RECORD_TYPE
)
1134 && (TREE_CODE (TREE_TYPE (e
)) == RECORD_TYPE
))
1135 assert ("converting COMPLEX to REAL" == NULL
);
1136 assert (code
!= ENUMERAL_TYPE
);
1137 if (code
== INTEGER_TYPE
)
1139 assert ((TREE_CODE (TREE_TYPE (e
)) == INTEGER_TYPE
1140 && TYPE_PRECISION (type
) <= TYPE_PRECISION (TREE_TYPE (e
)))
1141 || (TREE_CODE (TREE_TYPE (e
)) == POINTER_TYPE
1142 && (TYPE_PRECISION (type
)
1143 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e
))))));
1144 return fold (convert_to_integer (type
, e
));
1146 if (code
== POINTER_TYPE
)
1148 assert (TREE_CODE (TREE_TYPE (e
)) == POINTER_TYPE
);
1149 return fold (convert_to_pointer (type
, e
));
1151 if (code
== REAL_TYPE
)
1153 assert (TREE_CODE (TREE_TYPE (e
)) == REAL_TYPE
);
1154 assert (TYPE_PRECISION (type
) <= TYPE_PRECISION (TREE_TYPE (e
)));
1155 return fold (convert_to_real (type
, e
));
1157 if (code
== COMPLEX_TYPE
)
1159 assert (TREE_CODE (TREE_TYPE (e
)) == COMPLEX_TYPE
);
1160 assert (TYPE_PRECISION (TREE_TYPE (type
)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e
))));
1161 return fold (convert_to_complex (type
, e
));
1163 if (code
== RECORD_TYPE
)
1165 assert (TREE_CODE (TREE_TYPE (e
)) == RECORD_TYPE
);
1166 /* Check that at least the first field name agrees. */
1167 assert (DECL_NAME (TYPE_FIELDS (type
))
1168 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e
))));
1169 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type
)))
1170 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e
)))));
1171 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type
)))
1172 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e
)))))
1174 return fold (ffecom_convert_to_complex_ (type
, e
));
1177 assert ("conversion to non-scalar type requested" == NULL
);
1178 return error_mark_node
;
1181 /* Like gcc's convert(), but crashes if narrowing might happen. */
1184 ffecom_convert_widen_ (tree type
, tree expr
)
1186 register tree e
= expr
;
1187 register enum tree_code code
= TREE_CODE (type
);
1189 if (type
== TREE_TYPE (e
)
1190 || TREE_CODE (e
) == ERROR_MARK
)
1192 if (TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (TREE_TYPE (e
)))
1193 return fold (build1 (NOP_EXPR
, type
, e
));
1194 if (TREE_CODE (TREE_TYPE (e
)) == ERROR_MARK
1195 || code
== ERROR_MARK
)
1196 return error_mark_node
;
1197 if (TREE_CODE (TREE_TYPE (e
)) == VOID_TYPE
)
1199 assert ("void value not ignored as it ought to be" == NULL
);
1200 return error_mark_node
;
1202 assert (code
!= VOID_TYPE
);
1203 if ((code
!= RECORD_TYPE
)
1204 && (TREE_CODE (TREE_TYPE (e
)) == RECORD_TYPE
))
1205 assert ("narrowing COMPLEX to REAL" == NULL
);
1206 assert (code
!= ENUMERAL_TYPE
);
1207 if (code
== INTEGER_TYPE
)
1209 assert ((TREE_CODE (TREE_TYPE (e
)) == INTEGER_TYPE
1210 && TYPE_PRECISION (type
) >= TYPE_PRECISION (TREE_TYPE (e
)))
1211 || (TREE_CODE (TREE_TYPE (e
)) == POINTER_TYPE
1212 && (TYPE_PRECISION (type
)
1213 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e
))))));
1214 return fold (convert_to_integer (type
, e
));
1216 if (code
== POINTER_TYPE
)
1218 assert (TREE_CODE (TREE_TYPE (e
)) == POINTER_TYPE
);
1219 return fold (convert_to_pointer (type
, e
));
1221 if (code
== REAL_TYPE
)
1223 assert (TREE_CODE (TREE_TYPE (e
)) == REAL_TYPE
);
1224 assert (TYPE_PRECISION (type
) >= TYPE_PRECISION (TREE_TYPE (e
)));
1225 return fold (convert_to_real (type
, e
));
1227 if (code
== COMPLEX_TYPE
)
1229 assert (TREE_CODE (TREE_TYPE (e
)) == COMPLEX_TYPE
);
1230 assert (TYPE_PRECISION (TREE_TYPE (type
)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e
))));
1231 return fold (convert_to_complex (type
, e
));
1233 if (code
== RECORD_TYPE
)
1235 assert (TREE_CODE (TREE_TYPE (e
)) == RECORD_TYPE
);
1236 /* Check that at least the first field name agrees. */
1237 assert (DECL_NAME (TYPE_FIELDS (type
))
1238 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e
))));
1239 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type
)))
1240 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e
)))));
1241 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type
)))
1242 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e
)))))
1244 return fold (ffecom_convert_to_complex_ (type
, e
));
1247 assert ("conversion to non-scalar type requested" == NULL
);
1248 return error_mark_node
;
1251 /* Handles making a COMPLEX type, either the standard
1252 (but buggy?) gbe way, or the safer (but less elegant?)
1256 ffecom_make_complex_type_ (tree subtype
)
1262 if (ffe_is_emulate_complex ())
1264 type
= make_node (RECORD_TYPE
);
1265 realfield
= ffecom_decl_field (type
, NULL_TREE
, "r", subtype
);
1266 imagfield
= ffecom_decl_field (type
, realfield
, "i", subtype
);
1267 TYPE_FIELDS (type
) = realfield
;
1272 type
= make_node (COMPLEX_TYPE
);
1273 TREE_TYPE (type
) = subtype
;
1280 /* Chooses either the gbe or the f2c way to build a
1281 complex constant. */
1284 ffecom_build_complex_constant_ (tree type
, tree realpart
, tree imagpart
)
1288 if (ffe_is_emulate_complex ())
1290 bothparts
= build_tree_list (TYPE_FIELDS (type
), realpart
);
1291 TREE_CHAIN (bothparts
) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type
)), imagpart
);
1292 bothparts
= build_constructor (type
, bothparts
);
1296 bothparts
= build_complex (type
, realpart
, imagpart
);
1303 ffecom_arglist_expr_ (const char *c
, ffebld expr
)
1306 tree
*plist
= &list
;
1307 tree trail
= NULL_TREE
; /* Append char length args here. */
1308 tree
*ptrail
= &trail
;
1313 tree wanted
= NULL_TREE
;
1314 static const char zed
[] = "0";
1319 while (expr
!= NULL
)
1342 wanted
= ffecom_f2c_complex_type_node
;
1346 wanted
= ffecom_f2c_doublereal_type_node
;
1350 wanted
= ffecom_f2c_doublecomplex_type_node
;
1354 wanted
= ffecom_f2c_real_type_node
;
1358 wanted
= ffecom_f2c_integer_type_node
;
1362 wanted
= ffecom_f2c_longint_type_node
;
1366 assert ("bad argstring code" == NULL
);
1372 exprh
= ffebld_head (expr
);
1376 if ((wanted
== NULL_TREE
)
1379 (ffecom_tree_type
[ffeinfo_basictype (ffebld_info (exprh
))]
1380 [ffeinfo_kindtype (ffebld_info (exprh
))])
1381 == TYPE_MODE (wanted
))))
1383 = build_tree_list (NULL_TREE
,
1384 ffecom_arg_ptr_to_expr (exprh
,
1388 item
= ffecom_arg_expr (exprh
, &length
);
1389 item
= ffecom_convert_widen_ (wanted
, item
);
1392 item
= ffecom_1 (ADDR_EXPR
,
1393 build_pointer_type (TREE_TYPE (item
)),
1397 = build_tree_list (NULL_TREE
,
1401 plist
= &TREE_CHAIN (*plist
);
1402 expr
= ffebld_trail (expr
);
1403 if (length
!= NULL_TREE
)
1405 *ptrail
= build_tree_list (NULL_TREE
, length
);
1406 ptrail
= &TREE_CHAIN (*ptrail
);
1410 /* We've run out of args in the call; if the implementation expects
1411 more, supply null pointers for them, which the implementation can
1412 check to see if an arg was omitted. */
1414 while (*c
!= '\0' && *c
!= '0')
1419 assert ("missing arg to run-time routine!" == NULL
);
1434 assert ("bad arg string code" == NULL
);
1438 = build_tree_list (NULL_TREE
,
1440 plist
= &TREE_CHAIN (*plist
);
1449 ffecom_widest_expr_type_ (ffebld list
)
1452 ffebld widest
= NULL
;
1454 ffetype widest_type
= NULL
;
1457 for (; list
!= NULL
; list
= ffebld_trail (list
))
1459 item
= ffebld_head (list
);
1462 if ((widest
!= NULL
)
1463 && (ffeinfo_basictype (ffebld_info (item
))
1464 != ffeinfo_basictype (ffebld_info (widest
))))
1466 type
= ffeinfo_type (ffeinfo_basictype (ffebld_info (item
)),
1467 ffeinfo_kindtype (ffebld_info (item
)));
1468 if ((widest
== FFEINFO_kindtypeNONE
)
1469 || (ffetype_size (type
)
1470 > ffetype_size (widest_type
)))
1477 assert (widest
!= NULL
);
1478 t
= ffecom_tree_type
[ffeinfo_basictype (ffebld_info (widest
))]
1479 [ffeinfo_kindtype (ffebld_info (widest
))];
1480 assert (t
!= NULL_TREE
);
1484 /* Check whether a partial overlap between two expressions is possible.
1486 Can *starting* to write a portion of expr1 change the value
1487 computed (perhaps already, *partially*) by expr2?
1489 Currently, this is a concern only for a COMPLEX expr1. But if it
1490 isn't in COMMON or local EQUIVALENCE, since we don't support
1491 aliasing of arguments, it isn't a concern. */
1494 ffecom_possible_partial_overlap_ (ffebld expr1
, ffebld expr2 ATTRIBUTE_UNUSED
)
1499 switch (ffebld_op (expr1
))
1501 case FFEBLD_opSYMTER
:
1502 sym
= ffebld_symter (expr1
);
1505 case FFEBLD_opARRAYREF
:
1506 if (ffebld_op (ffebld_left (expr1
)) != FFEBLD_opSYMTER
)
1508 sym
= ffebld_symter (ffebld_left (expr1
));
1515 if (ffesymbol_where (sym
) != FFEINFO_whereCOMMON
1516 && (ffesymbol_where (sym
) != FFEINFO_whereLOCAL
1517 || ! (st
= ffesymbol_storage (sym
))
1518 || ! ffestorag_parent (st
)))
1521 /* It's in COMMON or local EQUIVALENCE. */
1526 /* Check whether dest and source might overlap. ffebld versions of these
1527 might or might not be passed, will be NULL if not.
1529 The test is really whether source_tree is modifiable and, if modified,
1530 might overlap destination such that the value(s) in the destination might
1531 change before it is finally modified. dest_* are the canonized
1532 destination itself. */
1535 ffecom_overlap_ (tree dest_decl
, tree dest_offset
, tree dest_size
,
1536 tree source_tree
, ffebld source UNUSED
, bool scalar_arg
)
1543 if (source_tree
== NULL_TREE
)
1546 switch (TREE_CODE (source_tree
))
1549 case IDENTIFIER_NODE
:
1560 case TRUNC_DIV_EXPR
:
1562 case FLOOR_DIV_EXPR
:
1563 case ROUND_DIV_EXPR
:
1564 case TRUNC_MOD_EXPR
:
1566 case FLOOR_MOD_EXPR
:
1567 case ROUND_MOD_EXPR
:
1569 case EXACT_DIV_EXPR
:
1570 case FIX_TRUNC_EXPR
:
1572 case FIX_FLOOR_EXPR
:
1573 case FIX_ROUND_EXPR
:
1587 case TRUTH_ANDIF_EXPR
:
1588 case TRUTH_ORIF_EXPR
:
1589 case TRUTH_AND_EXPR
:
1591 case TRUTH_XOR_EXPR
:
1592 case TRUTH_NOT_EXPR
:
1608 return ffecom_overlap_ (dest_decl
, dest_offset
, dest_size
,
1609 TREE_OPERAND (source_tree
, 1), NULL
,
1613 return ffecom_overlap_ (dest_decl
, dest_offset
, dest_size
,
1614 TREE_OPERAND (source_tree
, 0), NULL
,
1619 case NON_LVALUE_EXPR
:
1621 if (TREE_CODE (TREE_TYPE (source_tree
)) != POINTER_TYPE
)
1624 ffecom_tree_canonize_ptr_ (&source_decl
, &source_offset
,
1626 source_size
= TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree
)));
1631 ffecom_overlap_ (dest_decl
, dest_offset
, dest_size
,
1632 TREE_OPERAND (source_tree
, 1), NULL
,
1634 || ffecom_overlap_ (dest_decl
, dest_offset
, dest_size
,
1635 TREE_OPERAND (source_tree
, 2), NULL
,
1640 ffecom_tree_canonize_ref_ (&source_decl
, &source_offset
,
1642 TREE_OPERAND (source_tree
, 0));
1646 if (TREE_CODE (TREE_TYPE (source_tree
)) != POINTER_TYPE
)
1649 source_decl
= source_tree
;
1650 source_offset
= bitsize_zero_node
;
1651 source_size
= TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree
)));
1655 case REFERENCE_EXPR
:
1656 case PREDECREMENT_EXPR
:
1657 case PREINCREMENT_EXPR
:
1658 case POSTDECREMENT_EXPR
:
1659 case POSTINCREMENT_EXPR
:
1667 /* Come here when source_decl, source_offset, and source_size filled
1668 in appropriately. */
1670 if (source_decl
== NULL_TREE
)
1671 return FALSE
; /* No decl involved, so no overlap. */
1673 if (source_decl
!= dest_decl
)
1674 return FALSE
; /* Different decl, no overlap. */
1676 if (TREE_CODE (dest_size
) == ERROR_MARK
)
1677 return TRUE
; /* Assignment into entire assumed-size
1678 array? Shouldn't happen.... */
1680 t
= ffecom_2 (LE_EXPR
, integer_type_node
,
1681 ffecom_2 (PLUS_EXPR
, TREE_TYPE (dest_offset
),
1683 convert (TREE_TYPE (dest_offset
),
1685 convert (TREE_TYPE (dest_offset
),
1688 if (integer_onep (t
))
1689 return FALSE
; /* Destination precedes source. */
1692 || (source_size
== NULL_TREE
)
1693 || (TREE_CODE (source_size
) == ERROR_MARK
)
1694 || integer_zerop (source_size
))
1695 return TRUE
; /* No way to tell if dest follows source. */
1697 t
= ffecom_2 (LE_EXPR
, integer_type_node
,
1698 ffecom_2 (PLUS_EXPR
, TREE_TYPE (source_offset
),
1700 convert (TREE_TYPE (source_offset
),
1702 convert (TREE_TYPE (source_offset
),
1705 if (integer_onep (t
))
1706 return FALSE
; /* Destination follows source. */
1708 return TRUE
; /* Destination and source overlap. */
1711 /* Check whether dest might overlap any of a list of arguments or is
1712 in a COMMON area the callee might know about (and thus modify). */
1715 ffecom_args_overlapping_ (tree dest_tree
, ffebld dest UNUSED
, tree args
,
1716 tree callee_commons
, bool scalar_args
)
1723 ffecom_tree_canonize_ref_ (&dest_decl
, &dest_offset
, &dest_size
,
1726 if (dest_decl
== NULL_TREE
)
1727 return FALSE
; /* Seems unlikely! */
1729 /* If the decl cannot be determined reliably, or if its in COMMON
1730 and the callee isn't known to not futz with COMMON via other
1731 means, overlap might happen. */
1733 if ((TREE_CODE (dest_decl
) == ERROR_MARK
)
1734 || ((callee_commons
!= NULL_TREE
)
1735 && TREE_PUBLIC (dest_decl
)))
1738 for (; args
!= NULL_TREE
; args
= TREE_CHAIN (args
))
1740 if (((arg
= TREE_VALUE (args
)) != NULL_TREE
)
1741 && ffecom_overlap_ (dest_decl
, dest_offset
, dest_size
,
1742 arg
, NULL
, scalar_args
))
1749 /* Build a string for a variable name as used by NAMELIST. This means that
1750 if we're using the f2c library, we build an uppercase string, since
1754 ffecom_build_f2c_string_ (int i
, const char *s
)
1756 if (!ffe_is_f2c_library ())
1757 return build_string (i
, s
);
1766 if (((size_t) i
) > ARRAY_SIZE (space
))
1767 tmp
= malloc_new_ks (malloc_pool_image (), "f2c_string", i
);
1771 for (p
= s
, q
= tmp
; *p
!= '\0'; ++p
, ++q
)
1775 t
= build_string (i
, tmp
);
1777 if (((size_t) i
) > ARRAY_SIZE (space
))
1778 malloc_kill_ks (malloc_pool_image (), tmp
, i
);
1784 /* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1785 type to just get whatever the function returns), handling the
1786 f2c value-returning convention, if required, by prepending
1787 to the arglist a pointer to a temporary to receive the return value. */
1790 ffecom_call_ (tree fn
, ffeinfoKindtype kt
, bool is_f2c_complex
, tree type
,
1791 tree args
, tree dest_tree
, ffebld dest
, bool *dest_used
,
1792 tree callee_commons
, bool scalar_args
, tree hook
)
1797 if (dest_used
!= NULL
)
1802 if ((dest_used
== NULL
)
1804 || (ffeinfo_basictype (ffebld_info (dest
))
1805 != FFEINFO_basictypeCOMPLEX
)
1806 || (ffeinfo_kindtype (ffebld_info (dest
)) != kt
)
1807 || ((type
!= NULL_TREE
) && (TREE_TYPE (dest_tree
) != type
))
1808 || ffecom_args_overlapping_ (dest_tree
, dest
, args
,
1818 tempvar
= dest_tree
;
1823 = build_tree_list (NULL_TREE
,
1824 ffecom_1 (ADDR_EXPR
,
1825 build_pointer_type (TREE_TYPE (tempvar
)),
1827 TREE_CHAIN (item
) = args
;
1829 item
= ffecom_3s (CALL_EXPR
, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn
))), fn
,
1832 if (tempvar
!= dest_tree
)
1833 item
= ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (tempvar
), item
, tempvar
);
1836 item
= ffecom_3s (CALL_EXPR
, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn
))), fn
,
1839 if ((type
!= NULL_TREE
) && (TREE_TYPE (item
) != type
))
1840 item
= ffecom_convert_narrow_ (type
, item
);
1845 /* Given two arguments, transform them and make a call to the given
1846 function via ffecom_call_. */
1849 ffecom_call_binop_ (tree fn
, ffeinfoKindtype kt
, bool is_f2c_complex
,
1850 tree type
, ffebld left
, ffebld right
, tree dest_tree
,
1851 ffebld dest
, bool *dest_used
, tree callee_commons
,
1852 bool scalar_args
, bool ref
, tree hook
)
1861 /* Pass arguments by reference. */
1862 left_tree
= ffecom_arg_ptr_to_expr (left
, &left_length
);
1863 right_tree
= ffecom_arg_ptr_to_expr (right
, &right_length
);
1867 /* Pass arguments by value. */
1868 left_tree
= ffecom_arg_expr (left
, &left_length
);
1869 right_tree
= ffecom_arg_expr (right
, &right_length
);
1873 left_tree
= build_tree_list (NULL_TREE
, left_tree
);
1874 right_tree
= build_tree_list (NULL_TREE
, right_tree
);
1875 TREE_CHAIN (left_tree
) = right_tree
;
1877 if (left_length
!= NULL_TREE
)
1879 left_length
= build_tree_list (NULL_TREE
, left_length
);
1880 TREE_CHAIN (right_tree
) = left_length
;
1883 if (right_length
!= NULL_TREE
)
1885 right_length
= build_tree_list (NULL_TREE
, right_length
);
1886 if (left_length
!= NULL_TREE
)
1887 TREE_CHAIN (left_length
) = right_length
;
1889 TREE_CHAIN (right_tree
) = right_length
;
1892 return ffecom_call_ (fn
, kt
, is_f2c_complex
, type
, left_tree
,
1893 dest_tree
, dest
, dest_used
, callee_commons
,
1897 /* Return ptr/length args for char subexpression
1899 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1900 subexpressions by constructing the appropriate trees for the ptr-to-
1901 character-text and length-of-character-text arguments in a calling
1904 Note that if with_null is TRUE, and the expression is an opCONTER,
1905 a null byte is appended to the string. */
1908 ffecom_char_args_x_ (tree
*xitem
, tree
*length
, ffebld expr
, bool with_null
)
1912 ffetargetCharacter1 val
;
1913 ffetargetCharacterSize newlen
;
1915 switch (ffebld_op (expr
))
1917 case FFEBLD_opCONTER
:
1918 val
= ffebld_constant_character1 (ffebld_conter (expr
));
1919 newlen
= ffetarget_length_character1 (val
);
1922 /* Begin FFETARGET-NULL-KLUDGE. */
1926 *length
= build_int_2 (newlen
, 0);
1927 TREE_TYPE (*length
) = ffecom_f2c_ftnlen_type_node
;
1928 high
= build_int_2 (newlen
, 0);
1929 TREE_TYPE (high
) = ffecom_f2c_ftnlen_type_node
;
1930 item
= build_string (newlen
,
1931 ffetarget_text_character1 (val
));
1932 /* End FFETARGET-NULL-KLUDGE. */
1934 = build_type_variant
1938 (ffecom_f2c_ftnlen_type_node
,
1939 ffecom_f2c_ftnlen_one_node
,
1942 TREE_CONSTANT (item
) = 1;
1943 TREE_STATIC (item
) = 1;
1944 item
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (item
)),
1948 case FFEBLD_opSYMTER
:
1950 ffesymbol s
= ffebld_symter (expr
);
1952 item
= ffesymbol_hook (s
).decl_tree
;
1953 if (item
== NULL_TREE
)
1955 s
= ffecom_sym_transform_ (s
);
1956 item
= ffesymbol_hook (s
).decl_tree
;
1958 if (ffesymbol_kind (s
) == FFEINFO_kindENTITY
)
1960 if (ffesymbol_size (s
) == FFETARGET_charactersizeNONE
)
1961 *length
= ffesymbol_hook (s
).length_tree
;
1964 *length
= build_int_2 (ffesymbol_size (s
), 0);
1965 TREE_TYPE (*length
) = ffecom_f2c_ftnlen_type_node
;
1968 else if (item
== error_mark_node
)
1969 *length
= error_mark_node
;
1971 /* FFEINFO_kindFUNCTION. */
1972 *length
= NULL_TREE
;
1973 if (!ffesymbol_hook (s
).addr
1974 && (item
!= error_mark_node
))
1975 item
= ffecom_1 (ADDR_EXPR
,
1976 build_pointer_type (TREE_TYPE (item
)),
1981 case FFEBLD_opARRAYREF
:
1983 ffecom_char_args_ (&item
, length
, ffebld_left (expr
));
1985 if (item
== error_mark_node
|| *length
== error_mark_node
)
1987 item
= *length
= error_mark_node
;
1991 item
= ffecom_arrayref_ (item
, expr
, 1);
1995 case FFEBLD_opSUBSTR
:
1999 ffebld thing
= ffebld_right (expr
);
2002 const char *char_name
;
2006 assert (ffebld_op (thing
) == FFEBLD_opITEM
);
2007 start
= ffebld_head (thing
);
2008 thing
= ffebld_trail (thing
);
2009 assert (ffebld_trail (thing
) == NULL
);
2010 end
= ffebld_head (thing
);
2012 /* Determine name for pretty-printing range-check errors. */
2013 for (left_symter
= ffebld_left (expr
);
2014 left_symter
&& ffebld_op (left_symter
) == FFEBLD_opARRAYREF
;
2015 left_symter
= ffebld_left (left_symter
))
2017 if (ffebld_op (left_symter
) == FFEBLD_opSYMTER
)
2018 char_name
= ffesymbol_text (ffebld_symter (left_symter
));
2020 char_name
= "[expr?]";
2022 ffecom_char_args_ (&item
, length
, ffebld_left (expr
));
2024 if (item
== error_mark_node
|| *length
== error_mark_node
)
2026 item
= *length
= error_mark_node
;
2030 array
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item
)));
2032 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2040 end_tree
= ffecom_expr (end
);
2041 if (flag_bounds_check
)
2042 end_tree
= ffecom_subscript_check_ (array
, end_tree
, 1, 0,
2043 char_name
, NULL_TREE
);
2044 end_tree
= convert (ffecom_f2c_ftnlen_type_node
,
2047 if (end_tree
== error_mark_node
)
2049 item
= *length
= error_mark_node
;
2058 start_tree
= ffecom_expr (start
);
2059 if (flag_bounds_check
)
2060 start_tree
= ffecom_subscript_check_ (array
, start_tree
, 0, 0,
2061 char_name
, NULL_TREE
);
2062 start_tree
= convert (ffecom_f2c_ftnlen_type_node
,
2065 if (start_tree
== error_mark_node
)
2067 item
= *length
= error_mark_node
;
2071 start_tree
= ffecom_save_tree (start_tree
);
2073 item
= ffecom_2 (PLUS_EXPR
, TREE_TYPE (item
),
2075 ffecom_2 (MINUS_EXPR
,
2076 TREE_TYPE (start_tree
),
2078 ffecom_f2c_ftnlen_one_node
));
2082 *length
= ffecom_2 (PLUS_EXPR
, ffecom_f2c_ftnlen_type_node
,
2083 ffecom_f2c_ftnlen_one_node
,
2084 ffecom_2 (MINUS_EXPR
,
2085 ffecom_f2c_ftnlen_type_node
,
2091 end_tree
= ffecom_expr (end
);
2092 if (flag_bounds_check
)
2093 end_tree
= ffecom_subscript_check_ (array
, end_tree
, 1, 0,
2094 char_name
, NULL_TREE
);
2095 end_tree
= convert (ffecom_f2c_ftnlen_type_node
,
2098 if (end_tree
== error_mark_node
)
2100 item
= *length
= error_mark_node
;
2104 *length
= ffecom_2 (PLUS_EXPR
, ffecom_f2c_ftnlen_type_node
,
2105 ffecom_f2c_ftnlen_one_node
,
2106 ffecom_2 (MINUS_EXPR
,
2107 ffecom_f2c_ftnlen_type_node
,
2108 end_tree
, start_tree
));
2114 case FFEBLD_opFUNCREF
:
2116 ffesymbol s
= ffebld_symter (ffebld_left (expr
));
2119 ffetargetCharacterSize size
= ffeinfo_size (ffebld_info (expr
));
2122 if (size
== FFETARGET_charactersizeNONE
)
2123 /* ~~Kludge alert! This should someday be fixed. */
2126 *length
= build_int_2 (size
, 0);
2127 TREE_TYPE (*length
) = ffecom_f2c_ftnlen_type_node
;
2129 if (ffeinfo_where (ffebld_info (ffebld_left (expr
)))
2130 == FFEINFO_whereINTRINSIC
)
2134 /* Invocation of an intrinsic returning CHARACTER*1. */
2135 item
= ffecom_expr_intrinsic_ (expr
, NULL_TREE
,
2139 ix
= ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr
)));
2140 assert (ix
!= FFECOM_gfrt
);
2141 item
= ffecom_gfrt_tree_ (ix
);
2146 item
= ffesymbol_hook (s
).decl_tree
;
2147 if (item
== NULL_TREE
)
2149 s
= ffecom_sym_transform_ (s
);
2150 item
= ffesymbol_hook (s
).decl_tree
;
2152 if (item
== error_mark_node
)
2154 item
= *length
= error_mark_node
;
2158 if (!ffesymbol_hook (s
).addr
)
2159 item
= ffecom_1_fn (item
);
2161 tempvar
= ffebld_nonter_hook (expr
);
2163 tempvar
= ffecom_1 (ADDR_EXPR
,
2164 build_pointer_type (TREE_TYPE (tempvar
)),
2167 args
= build_tree_list (NULL_TREE
, tempvar
);
2169 if (ffesymbol_where (s
) == FFEINFO_whereCONSTANT
) /* Sfunc args by value. */
2170 TREE_CHAIN (args
) = ffecom_list_expr (ffebld_right (expr
));
2173 TREE_CHAIN (args
) = build_tree_list (NULL_TREE
, *length
);
2174 if (ffesymbol_where (s
) == FFEINFO_whereINTRINSIC
)
2176 TREE_CHAIN (TREE_CHAIN (args
))
2177 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix
),
2178 ffebld_right (expr
));
2182 TREE_CHAIN (TREE_CHAIN (args
))
2183 = ffecom_list_ptr_to_expr (ffebld_right (expr
));
2187 item
= ffecom_3s (CALL_EXPR
,
2188 TREE_TYPE (TREE_TYPE (TREE_TYPE (item
))),
2189 item
, args
, NULL_TREE
);
2190 item
= ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (tempvar
), item
,
2195 case FFEBLD_opCONVERT
:
2197 ffecom_char_args_ (&item
, length
, ffebld_left (expr
));
2199 if (item
== error_mark_node
|| *length
== error_mark_node
)
2201 item
= *length
= error_mark_node
;
2205 if ((ffebld_size_known (ffebld_left (expr
))
2206 == FFETARGET_charactersizeNONE
)
2207 || (ffebld_size_known (ffebld_left (expr
)) < (ffebld_size (expr
))))
2208 { /* Possible blank-padding needed, copy into
2214 tempvar
= ffebld_nonter_hook (expr
);
2216 tempvar
= ffecom_1 (ADDR_EXPR
,
2217 build_pointer_type (TREE_TYPE (tempvar
)),
2220 newlen
= build_int_2 (ffebld_size (expr
), 0);
2221 TREE_TYPE (newlen
) = ffecom_f2c_ftnlen_type_node
;
2223 args
= build_tree_list (NULL_TREE
, tempvar
);
2224 TREE_CHAIN (args
) = build_tree_list (NULL_TREE
, item
);
2225 TREE_CHAIN (TREE_CHAIN (args
)) = build_tree_list (NULL_TREE
, newlen
);
2226 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args
)))
2227 = build_tree_list (NULL_TREE
, *length
);
2229 item
= ffecom_call_gfrt (FFECOM_gfrtCOPY
, args
, NULL_TREE
);
2230 TREE_SIDE_EFFECTS (item
) = 1;
2231 item
= ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (tempvar
), fold (item
),
2236 { /* Just truncate the length. */
2237 *length
= build_int_2 (ffebld_size (expr
), 0);
2238 TREE_TYPE (*length
) = ffecom_f2c_ftnlen_type_node
;
2243 assert ("bad op for single char arg expr" == NULL
);
2251 /* Check the size of the type to be sure it doesn't overflow the
2252 "portable" capacities of the compiler back end. `dummy' types
2253 can generally overflow the normal sizes as long as the computations
2254 themselves don't overflow. A particular target of the back end
2255 must still enforce its size requirements, though, and the back
2256 end takes care of this in stor-layout.c. */
2259 ffecom_check_size_overflow_ (ffesymbol s
, tree type
, bool dummy
)
2261 if (TREE_CODE (type
) == ERROR_MARK
)
2264 if (TYPE_SIZE (type
) == NULL_TREE
)
2267 if (TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
)
2270 /* An array is too large if size is negative or the type_size overflows
2271 or its "upper half" is larger than 3 (which would make the signed
2272 byte size and offset computations overflow). */
2274 if ((tree_int_cst_sgn (TYPE_SIZE (type
)) < 0)
2275 || (!dummy
&& (TREE_INT_CST_HIGH (TYPE_SIZE (type
)) > 3
2276 || TREE_OVERFLOW (TYPE_SIZE (type
)))))
2278 ffebad_start (FFEBAD_ARRAY_LARGE
);
2279 ffebad_string (ffesymbol_text (s
));
2280 ffebad_here (0, ffesymbol_where_line (s
), ffesymbol_where_column (s
));
2283 return error_mark_node
;
2289 /* Builds a length argument (PARM_DECL). Also wraps type in an array type
2290 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2291 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2294 ffecom_char_enhance_arg_ (tree
*xtype
, ffesymbol s
)
2296 ffetargetCharacterSize sz
= ffesymbol_size (s
);
2301 if (ffesymbol_where (s
) == FFEINFO_whereCONSTANT
)
2302 tlen
= NULL_TREE
; /* A statement function, no length passed. */
2305 if (ffesymbol_where (s
) == FFEINFO_whereDUMMY
)
2306 tlen
= ffecom_get_invented_identifier ("__g77_length_%s",
2307 ffesymbol_text (s
));
2309 tlen
= ffecom_get_invented_identifier ("__g77_%s", "length");
2310 tlen
= build_decl (PARM_DECL
, tlen
, ffecom_f2c_ftnlen_type_node
);
2311 DECL_ARTIFICIAL (tlen
) = 1;
2314 if (sz
== FFETARGET_charactersizeNONE
)
2316 assert (tlen
!= NULL_TREE
);
2317 highval
= variable_size (tlen
);
2321 highval
= build_int_2 (sz
, 0);
2322 TREE_TYPE (highval
) = ffecom_f2c_ftnlen_type_node
;
2325 type
= build_array_type (type
,
2326 build_range_type (ffecom_f2c_ftnlen_type_node
,
2327 ffecom_f2c_ftnlen_one_node
,
2334 /* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2336 ffecomConcatList_ catlist;
2337 ffebld expr; // expr of CHARACTER basictype.
2338 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2339 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2341 Scans expr for character subexpressions, updates and returns catlist
2344 static ffecomConcatList_
2345 ffecom_concat_list_gather_ (ffecomConcatList_ catlist
, ffebld expr
,
2346 ffetargetCharacterSize max
)
2348 ffetargetCharacterSize sz
;
2355 if ((max
!= FFETARGET_charactersizeNONE
) && (catlist
.minlen
>= max
))
2356 return catlist
; /* Don't append any more items. */
2358 switch (ffebld_op (expr
))
2360 case FFEBLD_opCONTER
:
2361 case FFEBLD_opSYMTER
:
2362 case FFEBLD_opARRAYREF
:
2363 case FFEBLD_opFUNCREF
:
2364 case FFEBLD_opSUBSTR
:
2365 case FFEBLD_opCONVERT
: /* Callers should strip this off beforehand
2366 if they don't need to preserve it. */
2367 if (catlist
.count
== catlist
.max
)
2368 { /* Make a (larger) list. */
2372 newmax
= (catlist
.max
== 0) ? 8 : catlist
.max
* 2;
2373 newx
= malloc_new_ks (malloc_pool_image (), "catlist",
2374 newmax
* sizeof (newx
[0]));
2375 if (catlist
.max
!= 0)
2377 memcpy (newx
, catlist
.exprs
, catlist
.max
* sizeof (newx
[0]));
2378 malloc_kill_ks (malloc_pool_image (), catlist
.exprs
,
2379 catlist
.max
* sizeof (newx
[0]));
2381 catlist
.max
= newmax
;
2382 catlist
.exprs
= newx
;
2384 if ((sz
= ffebld_size_known (expr
)) != FFETARGET_charactersizeNONE
)
2385 catlist
.minlen
+= sz
;
2387 ++catlist
.minlen
; /* Not true for F90; can be 0 length. */
2388 if ((sz
= ffebld_size_max (expr
)) == FFETARGET_charactersizeNONE
)
2389 catlist
.maxlen
= sz
;
2391 catlist
.maxlen
+= sz
;
2392 if ((max
!= FFETARGET_charactersizeNONE
) && (catlist
.minlen
> max
))
2393 { /* This item overlaps (or is beyond) the end
2394 of the destination. */
2395 switch (ffebld_op (expr
))
2397 case FFEBLD_opCONTER
:
2398 case FFEBLD_opSYMTER
:
2399 case FFEBLD_opARRAYREF
:
2400 case FFEBLD_opFUNCREF
:
2401 case FFEBLD_opSUBSTR
:
2402 /* ~~Do useful truncations here. */
2406 assert ("op changed or inconsistent switches!" == NULL
);
2410 catlist
.exprs
[catlist
.count
++] = expr
;
2413 case FFEBLD_opPAREN
:
2414 expr
= ffebld_left (expr
);
2415 goto recurse
; /* :::::::::::::::::::: */
2417 case FFEBLD_opCONCATENATE
:
2418 catlist
= ffecom_concat_list_gather_ (catlist
, ffebld_left (expr
), max
);
2419 expr
= ffebld_right (expr
);
2420 goto recurse
; /* :::::::::::::::::::: */
2422 #if 0 /* Breaks passing small actual arg to larger
2423 dummy arg of sfunc */
2424 case FFEBLD_opCONVERT
:
2425 expr
= ffebld_left (expr
);
2427 ffetargetCharacterSize cmax
;
2429 cmax
= catlist
.len
+ ffebld_size_known (expr
);
2431 if ((max
== FFETARGET_charactersizeNONE
) || (max
> cmax
))
2434 goto recurse
; /* :::::::::::::::::::: */
2441 assert ("bad op in _gather_" == NULL
);
2446 /* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2448 ffecomConcatList_ catlist;
2449 ffecom_concat_list_kill_(catlist);
2451 Anything allocated within the list info is deallocated. */
2454 ffecom_concat_list_kill_ (ffecomConcatList_ catlist
)
2456 if (catlist
.max
!= 0)
2457 malloc_kill_ks (malloc_pool_image (), catlist
.exprs
,
2458 catlist
.max
* sizeof (catlist
.exprs
[0]));
2461 /* Make list of concatenated string exprs.
2463 Returns a flattened list of concatenated subexpressions given a
2464 tree of such expressions. */
2466 static ffecomConcatList_
2467 ffecom_concat_list_new_ (ffebld expr
, ffetargetCharacterSize max
)
2469 ffecomConcatList_ catlist
;
2471 catlist
.maxlen
= catlist
.minlen
= catlist
.max
= catlist
.count
= 0;
2472 return ffecom_concat_list_gather_ (catlist
, expr
, max
);
2475 /* Provide some kind of useful info on member of aggregate area,
2476 since current g77/gcc technology does not provide debug info
2477 on these members. */
2480 ffecom_debug_kludge_ (tree aggr
, const char *aggr_type
, ffesymbol member
,
2481 tree member_type UNUSED
, ffetargetOffset offset
)
2491 for (type_id
= member_type
;
2492 TREE_CODE (type_id
) != IDENTIFIER_NODE
;
2495 switch (TREE_CODE (type_id
))
2499 type_id
= TYPE_NAME (type_id
);
2504 type_id
= TREE_TYPE (type_id
);
2508 assert ("no IDENTIFIER_NODE for type!" == NULL
);
2509 type_id
= error_mark_node
;
2515 if (ffecom_transform_only_dummies_
2516 || !ffe_is_debug_kludge ())
2517 return; /* Can't do this yet, maybe later. */
2520 + strlen (aggr_type
)
2521 + IDENTIFIER_LENGTH (DECL_NAME (aggr
));
2523 + IDENTIFIER_LENGTH (type_id
);
2526 if (((size_t) len
) >= ARRAY_SIZE (space
))
2527 buff
= malloc_new_ks (malloc_pool_image (), "debug_kludge", len
+ 1);
2531 sprintf (&buff
[0], "At (%s) `%s' plus %ld bytes",
2533 IDENTIFIER_POINTER (DECL_NAME (aggr
)),
2536 value
= build_string (len
, buff
);
2538 = build_type_variant (build_array_type (char_type_node
,
2542 build_int_2 (strlen (buff
), 0))),
2544 decl
= build_decl (VAR_DECL
,
2545 ffecom_get_identifier_ (ffesymbol_text (member
)),
2547 TREE_CONSTANT (decl
) = 1;
2548 TREE_STATIC (decl
) = 1;
2549 DECL_INITIAL (decl
) = error_mark_node
;
2550 DECL_IN_SYSTEM_HEADER (decl
) = 1; /* Don't let -Wunused complain. */
2551 decl
= start_decl (decl
, FALSE
);
2552 finish_decl (decl
, value
, FALSE
);
2554 if (buff
!= &space
[0])
2555 malloc_kill_ks (malloc_pool_image (), buff
, len
+ 1);
2558 /* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2560 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2561 int i; // entry# for this entrypoint (used by master fn)
2562 ffecom_do_entrypoint_(s,i);
2564 Makes a public entry point that calls our private master fn (already
2568 ffecom_do_entry_ (ffesymbol fn
, int entrynum
)
2571 tree type
; /* Type of function. */
2572 tree multi_retval
; /* Var holding return value (union). */
2573 tree result
; /* Var holding result. */
2574 ffeinfoBasictype bt
;
2578 bool charfunc
; /* All entry points return same type
2580 bool cmplxfunc
; /* Use f2c way of returning COMPLEX. */
2581 bool multi
; /* Master fn has multiple return types. */
2582 bool altreturning
= FALSE
; /* This entry point has alternate
2584 location_t old_loc
= input_location
;
2586 input_filename
= ffesymbol_where_filename (fn
);
2587 input_line
= ffesymbol_where_filelinenum (fn
);
2589 ffecom_doing_entry_
= TRUE
; /* Don't bother with array dimensions. */
2591 switch (ffecom_primary_entry_kind_
)
2593 case FFEINFO_kindFUNCTION
:
2595 /* Determine actual return type for function. */
2597 gt
= FFEGLOBAL_typeFUNC
;
2598 bt
= ffesymbol_basictype (fn
);
2599 kt
= ffesymbol_kindtype (fn
);
2600 if (bt
== FFEINFO_basictypeNONE
)
2602 ffeimplic_establish_symbol (fn
);
2603 if (ffesymbol_funcresult (fn
) != NULL
)
2604 ffeimplic_establish_symbol (ffesymbol_funcresult (fn
));
2605 bt
= ffesymbol_basictype (fn
);
2606 kt
= ffesymbol_kindtype (fn
);
2609 if (bt
== FFEINFO_basictypeCHARACTER
)
2610 charfunc
= TRUE
, cmplxfunc
= FALSE
;
2611 else if ((bt
== FFEINFO_basictypeCOMPLEX
)
2612 && ffesymbol_is_f2c (fn
))
2613 charfunc
= FALSE
, cmplxfunc
= TRUE
;
2615 charfunc
= cmplxfunc
= FALSE
;
2618 type
= ffecom_tree_fun_type_void
;
2619 else if (ffesymbol_is_f2c (fn
))
2620 type
= ffecom_tree_fun_type
[bt
][kt
];
2622 type
= build_function_type (ffecom_tree_type
[bt
][kt
], NULL_TREE
);
2624 if ((type
== NULL_TREE
)
2625 || (TREE_TYPE (type
) == NULL_TREE
))
2626 type
= ffecom_tree_fun_type_void
; /* _sym_exec_transition. */
2628 multi
= (ffecom_master_bt_
== FFEINFO_basictypeNONE
);
2631 case FFEINFO_kindSUBROUTINE
:
2632 gt
= FFEGLOBAL_typeSUBR
;
2633 bt
= FFEINFO_basictypeNONE
;
2634 kt
= FFEINFO_kindtypeNONE
;
2635 if (ffecom_is_altreturning_
)
2636 { /* Am _I_ altreturning? */
2637 for (item
= ffesymbol_dummyargs (fn
);
2639 item
= ffebld_trail (item
))
2641 if (ffebld_op (ffebld_head (item
)) == FFEBLD_opSTAR
)
2643 altreturning
= TRUE
;
2648 type
= ffecom_tree_subr_type
;
2650 type
= ffecom_tree_fun_type_void
;
2653 type
= ffecom_tree_fun_type_void
;
2660 assert ("say what??" == NULL
);
2662 case FFEINFO_kindANY
:
2663 gt
= FFEGLOBAL_typeANY
;
2664 bt
= FFEINFO_basictypeNONE
;
2665 kt
= FFEINFO_kindtypeNONE
;
2666 type
= error_mark_node
;
2673 /* build_decl uses the current lineno and input_filename to set the decl
2674 source info. So, I've putzed with ffestd and ffeste code to update that
2675 source info to point to the appropriate statement just before calling
2676 ffecom_do_entrypoint (which calls this fn). */
2678 start_function (ffecom_get_external_identifier_ (fn
),
2680 0, /* nested/inline */
2681 1); /* TREE_PUBLIC */
2683 if (((g
= ffesymbol_global (fn
)) != NULL
)
2684 && ((ffeglobal_type (g
) == gt
)
2685 || (ffeglobal_type (g
) == FFEGLOBAL_typeEXT
)))
2687 ffeglobal_set_hook (g
, current_function_decl
);
2690 /* Reset args in master arg list so they get retransitioned. */
2692 for (item
= ffecom_master_arglist_
;
2694 item
= ffebld_trail (item
))
2699 arg
= ffebld_head (item
);
2700 if (ffebld_op (arg
) != FFEBLD_opSYMTER
)
2701 continue; /* Alternate return or some such thing. */
2702 s
= ffebld_symter (arg
);
2703 ffesymbol_hook (s
).decl_tree
= NULL_TREE
;
2704 ffesymbol_hook (s
).length_tree
= NULL_TREE
;
2707 /* Build dummy arg list for this entry point. */
2709 if (charfunc
|| cmplxfunc
)
2710 { /* Prepend arg for where result goes. */
2715 type
= ffecom_tree_type
[FFEINFO_basictypeCHARACTER
][kt
];
2717 type
= ffecom_tree_type
[FFEINFO_basictypeCOMPLEX
][kt
];
2719 result
= ffecom_get_invented_identifier ("__g77_%s", "result");
2721 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2724 length
= ffecom_char_enhance_arg_ (&type
, fn
);
2726 length
= NULL_TREE
; /* Not ref'd if !charfunc. */
2728 type
= build_pointer_type (type
);
2729 result
= build_decl (PARM_DECL
, result
, type
);
2731 push_parm_decl (result
);
2732 ffecom_func_result_
= result
;
2736 push_parm_decl (length
);
2737 ffecom_func_length_
= length
;
2741 result
= DECL_RESULT (current_function_decl
);
2743 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn
), FALSE
);
2745 store_parm_decls (0);
2747 ffecom_start_compstmt ();
2748 /* Disallow temp vars at this level. */
2749 current_binding_level
->prep_state
= 2;
2751 /* Make local var to hold return type for multi-type master fn. */
2755 multi_retval
= ffecom_get_invented_identifier ("__g77_%s",
2757 multi_retval
= build_decl (VAR_DECL
, multi_retval
,
2758 ffecom_multi_type_node_
);
2759 multi_retval
= start_decl (multi_retval
, FALSE
);
2760 finish_decl (multi_retval
, NULL_TREE
, FALSE
);
2763 multi_retval
= NULL_TREE
; /* Not actually ref'd if !multi. */
2765 /* Here we emit the actual code for the entry point. */
2771 tree arglist
= NULL_TREE
;
2772 tree
*plist
= &arglist
;
2778 /* Prepare actual arg list based on master arg list. */
2780 for (list
= ffecom_master_arglist_
;
2782 list
= ffebld_trail (list
))
2784 arg
= ffebld_head (list
);
2785 if (ffebld_op (arg
) != FFEBLD_opSYMTER
)
2787 s
= ffebld_symter (arg
);
2788 if (ffesymbol_hook (s
).decl_tree
== NULL_TREE
2789 || ffesymbol_hook (s
).decl_tree
== error_mark_node
)
2790 actarg
= null_pointer_node
; /* We don't have this arg. */
2792 actarg
= ffesymbol_hook (s
).decl_tree
;
2793 *plist
= build_tree_list (NULL_TREE
, actarg
);
2794 plist
= &TREE_CHAIN (*plist
);
2797 /* This code appends the length arguments for character
2798 variables/arrays. */
2800 for (list
= ffecom_master_arglist_
;
2802 list
= ffebld_trail (list
))
2804 arg
= ffebld_head (list
);
2805 if (ffebld_op (arg
) != FFEBLD_opSYMTER
)
2807 s
= ffebld_symter (arg
);
2808 if (ffesymbol_basictype (s
) != FFEINFO_basictypeCHARACTER
)
2809 continue; /* Only looking for CHARACTER arguments. */
2810 if (ffesymbol_kind (s
) != FFEINFO_kindENTITY
)
2811 continue; /* Only looking for variables and arrays. */
2812 if (ffesymbol_hook (s
).length_tree
== NULL_TREE
2813 || ffesymbol_hook (s
).length_tree
== error_mark_node
)
2814 actarg
= ffecom_f2c_ftnlen_zero_node
; /* We don't have this arg. */
2816 actarg
= ffesymbol_hook (s
).length_tree
;
2817 *plist
= build_tree_list (NULL_TREE
, actarg
);
2818 plist
= &TREE_CHAIN (*plist
);
2821 /* Prepend character-value return info to actual arg list. */
2825 prepend
= build_tree_list (NULL_TREE
, ffecom_func_result_
);
2826 TREE_CHAIN (prepend
)
2827 = build_tree_list (NULL_TREE
, ffecom_func_length_
);
2828 TREE_CHAIN (TREE_CHAIN (prepend
)) = arglist
;
2832 /* Prepend multi-type return value to actual arg list. */
2837 = build_tree_list (NULL_TREE
,
2838 ffecom_1 (ADDR_EXPR
,
2839 build_pointer_type (TREE_TYPE (multi_retval
)),
2841 TREE_CHAIN (prepend
) = arglist
;
2845 /* Prepend my entry-point number to the actual arg list. */
2847 prepend
= build_tree_list (NULL_TREE
, build_int_2 (entrynum
, 0));
2848 TREE_CHAIN (prepend
) = arglist
;
2851 /* Build the call to the master function. */
2853 master_fn
= ffecom_1_fn (ffecom_previous_function_decl_
);
2854 call
= ffecom_3s (CALL_EXPR
,
2855 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn
))),
2856 master_fn
, arglist
, NULL_TREE
);
2858 /* Decide whether the master function is a function or subroutine, and
2859 handle the return value for my entry point. */
2861 if (charfunc
|| ((ffecom_primary_entry_kind_
== FFEINFO_kindSUBROUTINE
)
2864 expand_expr_stmt (call
);
2865 expand_null_return ();
2867 else if (multi
&& cmplxfunc
)
2869 expand_expr_stmt (call
);
2871 = ffecom_1 (INDIRECT_REF
,
2872 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result
))),
2874 result
= ffecom_modify (NULL_TREE
, result
,
2875 ffecom_2 (COMPONENT_REF
, TREE_TYPE (result
),
2877 ffecom_multi_fields_
[bt
][kt
]));
2878 expand_expr_stmt (result
);
2879 expand_null_return ();
2883 expand_expr_stmt (call
);
2885 = ffecom_modify (NULL_TREE
, result
,
2886 convert (TREE_TYPE (result
),
2887 ffecom_2 (COMPONENT_REF
,
2888 ffecom_tree_type
[bt
][kt
],
2890 ffecom_multi_fields_
[bt
][kt
])));
2891 expand_return (result
);
2896 = ffecom_1 (INDIRECT_REF
,
2897 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result
))),
2899 result
= ffecom_modify (NULL_TREE
, result
, call
);
2900 expand_expr_stmt (result
);
2901 expand_null_return ();
2905 result
= ffecom_modify (NULL_TREE
,
2907 convert (TREE_TYPE (result
),
2909 expand_return (result
);
2913 ffecom_end_compstmt ();
2915 finish_function (0);
2917 input_location
= old_loc
;
2919 ffecom_doing_entry_
= FALSE
;
2922 /* Transform expr into gcc tree with possible destination
2924 Recursive descent on expr while making corresponding tree nodes and
2925 attaching type info and such. If destination supplied and compatible
2926 with temporary that would be made in certain cases, temporary isn't
2927 made, destination used instead, and dest_used flag set TRUE. */
2930 ffecom_expr_ (ffebld expr
, tree dest_tree
, ffebld dest
, bool *dest_used
,
2931 bool assignp
, bool widenp
)
2936 ffeinfoBasictype bt
;
2939 tree dt
; /* decl_tree for an ffesymbol. */
2940 tree tree_type
, tree_type_x
;
2943 enum tree_code code
;
2945 assert (expr
!= NULL
);
2947 if (dest_used
!= NULL
)
2950 bt
= ffeinfo_basictype (ffebld_info (expr
));
2951 kt
= ffeinfo_kindtype (ffebld_info (expr
));
2952 tree_type
= ffecom_tree_type
[bt
][kt
];
2954 /* Widen integral arithmetic as desired while preserving signedness. */
2955 tree_type_x
= NULL_TREE
;
2956 if (widenp
&& tree_type
2957 && GET_MODE_CLASS (TYPE_MODE (tree_type
)) == MODE_INT
2958 && TYPE_PRECISION (tree_type
) < TYPE_PRECISION (sizetype
))
2959 tree_type_x
= (TYPE_UNSIGNED (tree_type
) ? usizetype
: ssizetype
);
2961 switch (ffebld_op (expr
))
2963 case FFEBLD_opACCTER
:
2966 ffebit bits
= ffebld_accter_bits (expr
);
2967 ffetargetOffset source_offset
= 0;
2968 ffetargetOffset dest_offset
= ffebld_accter_pad (expr
);
2971 assert (dest_offset
== 0
2972 || (bt
== FFEINFO_basictypeCHARACTER
2973 && kt
== FFEINFO_kindtypeCHARACTER1
));
2978 ffebldConstantUnion cu
;
2981 ffebldConstantArray ca
= ffebld_accter (expr
);
2983 ffebit_test (bits
, source_offset
, &value
, &length
);
2989 for (i
= 0; i
< length
; ++i
)
2991 cu
= ffebld_constantarray_get (ca
, bt
, kt
,
2994 t
= ffecom_constantunion (&cu
, bt
, kt
, tree_type
);
2997 && dest_offset
!= 0)
2998 purpose
= build_int_2 (dest_offset
, 0);
3000 purpose
= NULL_TREE
;
3002 if (list
== NULL_TREE
)
3003 list
= item
= build_tree_list (purpose
, t
);
3006 TREE_CHAIN (item
) = build_tree_list (purpose
, t
);
3007 item
= TREE_CHAIN (item
);
3011 source_offset
+= length
;
3012 dest_offset
+= length
;
3016 item
= build_int_2 ((ffebld_accter_size (expr
)
3017 + ffebld_accter_pad (expr
)) - 1, 0);
3018 ffebit_kill (ffebld_accter_bits (expr
));
3019 TREE_TYPE (item
) = ffecom_integer_type_node
;
3023 build_range_type (ffecom_integer_type_node
,
3024 ffecom_integer_zero_node
,
3026 list
= build_constructor (item
, list
);
3027 TREE_CONSTANT (list
) = 1;
3028 TREE_STATIC (list
) = 1;
3031 case FFEBLD_opARRTER
:
3036 if (ffebld_arrter_pad (expr
) == 0)
3040 assert (bt
== FFEINFO_basictypeCHARACTER
3041 && kt
== FFEINFO_kindtypeCHARACTER1
);
3043 /* Becomes PURPOSE first time through loop. */
3044 item
= build_int_2 (ffebld_arrter_pad (expr
), 0);
3047 for (i
= 0; i
< ffebld_arrter_size (expr
); ++i
)
3049 ffebldConstantUnion cu
3050 = ffebld_constantarray_get (ffebld_arrter (expr
), bt
, kt
, i
);
3052 t
= ffecom_constantunion (&cu
, bt
, kt
, tree_type
);
3054 if (list
== NULL_TREE
)
3055 /* Assume item is PURPOSE first time through loop. */
3056 list
= item
= build_tree_list (item
, t
);
3059 TREE_CHAIN (item
) = build_tree_list (NULL_TREE
, t
);
3060 item
= TREE_CHAIN (item
);
3065 item
= build_int_2 ((ffebld_arrter_size (expr
)
3066 + ffebld_arrter_pad (expr
)) - 1, 0);
3067 TREE_TYPE (item
) = ffecom_integer_type_node
;
3071 build_range_type (ffecom_integer_type_node
,
3072 ffecom_integer_zero_node
,
3074 list
= build_constructor (item
, list
);
3075 TREE_CONSTANT (list
) = 1;
3076 TREE_STATIC (list
) = 1;
3079 case FFEBLD_opCONTER
:
3080 assert (ffebld_conter_pad (expr
) == 0);
3082 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr
)),
3086 case FFEBLD_opSYMTER
:
3087 if ((ffebld_symter_generic (expr
) != FFEINTRIN_genNONE
)
3088 || (ffebld_symter_specific (expr
) != FFEINTRIN_specNONE
))
3089 return ffecom_ptr_to_expr (expr
); /* Same as %REF(intrinsic). */
3090 s
= ffebld_symter (expr
);
3091 t
= ffesymbol_hook (s
).decl_tree
;
3094 { /* ASSIGN'ed-label expr. */
3095 if (ffe_is_ugly_assign ())
3097 /* User explicitly wants ASSIGN'ed variables to be at the same
3098 memory address as the variables when used in non-ASSIGN
3099 contexts. That can make old, arcane, non-standard code
3100 work, but don't try to do it when a pointer wouldn't fit
3101 in the normal variable (take other approach, and warn,
3106 s
= ffecom_sym_transform_ (s
);
3107 t
= ffesymbol_hook (s
).decl_tree
;
3108 assert (t
!= NULL_TREE
);
3111 if (t
== error_mark_node
)
3114 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t
)))
3115 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node
))))
3117 if (ffesymbol_hook (s
).addr
)
3118 t
= ffecom_1 (INDIRECT_REF
,
3119 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t
))), t
);
3123 if (ffesymbol_hook (s
).assign_tree
== NULL_TREE
)
3125 /* xgettext:no-c-format */
3126 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3127 FFEBAD_severityWARNING
);
3128 ffebad_string (ffesymbol_text (s
));
3129 ffebad_here (0, ffesymbol_where_line (s
),
3130 ffesymbol_where_column (s
));
3135 /* Don't use the normal variable's tree for ASSIGN, though mark
3136 it as in the system header (housekeeping). Use an explicit,
3137 specially created sibling that is known to be wide enough
3138 to hold pointers to labels. */
3141 && TREE_CODE (t
) == VAR_DECL
)
3142 DECL_IN_SYSTEM_HEADER (t
) = 1; /* Don't let -Wunused complain. */
3144 t
= ffesymbol_hook (s
).assign_tree
;
3147 s
= ffecom_sym_transform_assign_ (s
);
3148 t
= ffesymbol_hook (s
).assign_tree
;
3149 assert (t
!= NULL_TREE
);
3156 s
= ffecom_sym_transform_ (s
);
3157 t
= ffesymbol_hook (s
).decl_tree
;
3158 assert (t
!= NULL_TREE
);
3160 if (ffesymbol_hook (s
).addr
)
3161 t
= ffecom_1 (INDIRECT_REF
,
3162 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t
))), t
);
3166 case FFEBLD_opARRAYREF
:
3167 return ffecom_arrayref_ (NULL_TREE
, expr
, 0);
3169 case FFEBLD_opUPLUS
:
3170 left
= ffecom_expr_ (ffebld_left (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3171 return ffecom_1 (NOP_EXPR
, tree_type
, left
);
3173 case FFEBLD_opPAREN
:
3174 /* ~~~Make sure Fortran rules respected here */
3175 left
= ffecom_expr_ (ffebld_left (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3176 return ffecom_1 (NOP_EXPR
, tree_type
, left
);
3178 case FFEBLD_opUMINUS
:
3179 left
= ffecom_expr_ (ffebld_left (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3182 tree_type
= tree_type_x
;
3183 left
= convert (tree_type
, left
);
3185 return ffecom_1 (NEGATE_EXPR
, tree_type
, left
);
3188 left
= ffecom_expr_ (ffebld_left (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3189 right
= ffecom_expr_ (ffebld_right (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3192 tree_type
= tree_type_x
;
3193 left
= convert (tree_type
, left
);
3194 right
= convert (tree_type
, right
);
3196 return ffecom_2 (PLUS_EXPR
, tree_type
, left
, right
);
3198 case FFEBLD_opSUBTRACT
:
3199 left
= ffecom_expr_ (ffebld_left (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3200 right
= ffecom_expr_ (ffebld_right (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3203 tree_type
= tree_type_x
;
3204 left
= convert (tree_type
, left
);
3205 right
= convert (tree_type
, right
);
3207 return ffecom_2 (MINUS_EXPR
, tree_type
, left
, right
);
3209 case FFEBLD_opMULTIPLY
:
3210 left
= ffecom_expr_ (ffebld_left (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3211 right
= ffecom_expr_ (ffebld_right (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3214 tree_type
= tree_type_x
;
3215 left
= convert (tree_type
, left
);
3216 right
= convert (tree_type
, right
);
3218 return ffecom_2 (MULT_EXPR
, tree_type
, left
, right
);
3220 case FFEBLD_opDIVIDE
:
3221 left
= ffecom_expr_ (ffebld_left (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3222 right
= ffecom_expr_ (ffebld_right (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3225 tree_type
= tree_type_x
;
3226 left
= convert (tree_type
, left
);
3227 right
= convert (tree_type
, right
);
3229 return ffecom_tree_divide_ (tree_type
, left
, right
,
3230 dest_tree
, dest
, dest_used
,
3231 ffebld_nonter_hook (expr
));
3233 case FFEBLD_opPOWER
:
3235 ffebld left
= ffebld_left (expr
);
3236 ffebld right
= ffebld_right (expr
);
3238 ffeinfoKindtype rtkt
;
3239 ffeinfoKindtype ltkt
;
3242 switch (ffeinfo_basictype (ffebld_info (right
)))
3245 case FFEINFO_basictypeINTEGER
:
3248 item
= ffecom_expr_power_integer_ (expr
);
3249 if (item
!= NULL_TREE
)
3253 rtkt
= FFEINFO_kindtypeINTEGER1
;
3254 switch (ffeinfo_basictype (ffebld_info (left
)))
3256 case FFEINFO_basictypeINTEGER
:
3257 if ((ffeinfo_kindtype (ffebld_info (left
))
3258 == FFEINFO_kindtypeINTEGER4
)
3259 || (ffeinfo_kindtype (ffebld_info (right
))
3260 == FFEINFO_kindtypeINTEGER4
))
3262 code
= FFECOM_gfrtPOW_QQ
;
3263 ltkt
= FFEINFO_kindtypeINTEGER4
;
3264 rtkt
= FFEINFO_kindtypeINTEGER4
;
3268 code
= FFECOM_gfrtPOW_II
;
3269 ltkt
= FFEINFO_kindtypeINTEGER1
;
3273 case FFEINFO_basictypeREAL
:
3274 if (ffeinfo_kindtype (ffebld_info (left
))
3275 == FFEINFO_kindtypeREAL1
)
3277 code
= FFECOM_gfrtPOW_RI
;
3278 ltkt
= FFEINFO_kindtypeREAL1
;
3282 code
= FFECOM_gfrtPOW_DI
;
3283 ltkt
= FFEINFO_kindtypeREAL2
;
3287 case FFEINFO_basictypeCOMPLEX
:
3288 if (ffeinfo_kindtype (ffebld_info (left
))
3289 == FFEINFO_kindtypeREAL1
)
3291 code
= FFECOM_gfrtPOW_CI
; /* Overlapping result okay. */
3292 ltkt
= FFEINFO_kindtypeREAL1
;
3296 code
= FFECOM_gfrtPOW_ZI
; /* Overlapping result okay. */
3297 ltkt
= FFEINFO_kindtypeREAL2
;
3302 assert ("bad pow_*i" == NULL
);
3303 code
= FFECOM_gfrtPOW_CI
; /* Overlapping result okay. */
3304 ltkt
= FFEINFO_kindtypeREAL1
;
3307 if (ffeinfo_kindtype (ffebld_info (left
)) != ltkt
)
3308 left
= ffeexpr_convert (left
, NULL
, NULL
,
3309 ffeinfo_basictype (ffebld_info (left
)),
3311 FFETARGET_charactersizeNONE
,
3312 FFEEXPR_contextLET
);
3313 if (ffeinfo_kindtype (ffebld_info (right
)) != rtkt
)
3314 right
= ffeexpr_convert (right
, NULL
, NULL
,
3315 FFEINFO_basictypeINTEGER
,
3317 FFETARGET_charactersizeNONE
,
3318 FFEEXPR_contextLET
);
3321 case FFEINFO_basictypeREAL
:
3322 if (ffeinfo_kindtype (ffebld_info (left
)) == FFEINFO_kindtypeREAL1
)
3323 left
= ffeexpr_convert (left
, NULL
, NULL
, FFEINFO_basictypeREAL
,
3324 FFEINFO_kindtypeREALDOUBLE
, 0,
3325 FFETARGET_charactersizeNONE
,
3326 FFEEXPR_contextLET
);
3327 if (ffeinfo_kindtype (ffebld_info (right
))
3328 == FFEINFO_kindtypeREAL1
)
3329 right
= ffeexpr_convert (right
, NULL
, NULL
,
3330 FFEINFO_basictypeREAL
,
3331 FFEINFO_kindtypeREALDOUBLE
, 0,
3332 FFETARGET_charactersizeNONE
,
3333 FFEEXPR_contextLET
);
3334 /* We used to call FFECOM_gfrtPOW_DD here,
3335 which passes arguments by reference. */
3336 code
= FFECOM_gfrtL_POW
;
3337 /* Pass arguments by value. */
3341 case FFEINFO_basictypeCOMPLEX
:
3342 if (ffeinfo_kindtype (ffebld_info (left
)) == FFEINFO_kindtypeREAL1
)
3343 left
= ffeexpr_convert (left
, NULL
, NULL
,
3344 FFEINFO_basictypeCOMPLEX
,
3345 FFEINFO_kindtypeREALDOUBLE
, 0,
3346 FFETARGET_charactersizeNONE
,
3347 FFEEXPR_contextLET
);
3348 if (ffeinfo_kindtype (ffebld_info (right
))
3349 == FFEINFO_kindtypeREAL1
)
3350 right
= ffeexpr_convert (right
, NULL
, NULL
,
3351 FFEINFO_basictypeCOMPLEX
,
3352 FFEINFO_kindtypeREALDOUBLE
, 0,
3353 FFETARGET_charactersizeNONE
,
3354 FFEEXPR_contextLET
);
3355 code
= FFECOM_gfrtPOW_ZZ
; /* Overlapping result okay. */
3356 ref
= TRUE
; /* Pass arguments by reference. */
3360 assert ("bad pow_x*" == NULL
);
3361 code
= FFECOM_gfrtPOW_II
;
3364 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code
),
3365 ffecom_gfrt_kindtype (code
),
3366 (ffe_is_f2c_library ()
3367 && ffecom_gfrt_complex_
[code
]),
3368 tree_type
, left
, right
,
3369 dest_tree
, dest
, dest_used
,
3370 NULL_TREE
, FALSE
, ref
,
3371 ffebld_nonter_hook (expr
));
3377 case FFEINFO_basictypeLOGICAL
:
3378 item
= ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr
)));
3379 return convert (tree_type
, item
);
3381 case FFEINFO_basictypeINTEGER
:
3382 return ffecom_1 (BIT_NOT_EXPR
, tree_type
,
3383 ffecom_expr (ffebld_left (expr
)));
3386 assert ("NOT bad basictype" == NULL
);
3388 case FFEINFO_basictypeANY
:
3389 return error_mark_node
;
3393 case FFEBLD_opFUNCREF
:
3394 assert (ffeinfo_basictype (ffebld_info (expr
))
3395 != FFEINFO_basictypeCHARACTER
);
3397 case FFEBLD_opSUBRREF
:
3398 if (ffeinfo_where (ffebld_info (ffebld_left (expr
)))
3399 == FFEINFO_whereINTRINSIC
)
3400 { /* Invocation of an intrinsic. */
3401 item
= ffecom_expr_intrinsic_ (expr
, dest_tree
, dest
,
3405 s
= ffebld_symter (ffebld_left (expr
));
3406 dt
= ffesymbol_hook (s
).decl_tree
;
3407 if (dt
== NULL_TREE
)
3409 s
= ffecom_sym_transform_ (s
);
3410 dt
= ffesymbol_hook (s
).decl_tree
;
3412 if (dt
== error_mark_node
)
3415 if (ffesymbol_hook (s
).addr
)
3418 item
= ffecom_1_fn (dt
);
3420 if (ffesymbol_where (s
) == FFEINFO_whereCONSTANT
)
3421 args
= ffecom_list_expr (ffebld_right (expr
));
3423 args
= ffecom_list_ptr_to_expr (ffebld_right (expr
));
3425 if (args
== error_mark_node
)
3426 return error_mark_node
;
3428 item
= ffecom_call_ (item
, kt
,
3429 ffesymbol_is_f2c (s
)
3430 && (bt
== FFEINFO_basictypeCOMPLEX
)
3431 && (ffesymbol_where (s
)
3432 != FFEINFO_whereCONSTANT
),
3435 dest_tree
, dest
, dest_used
,
3436 error_mark_node
, FALSE
,
3437 ffebld_nonter_hook (expr
));
3438 TREE_SIDE_EFFECTS (item
) = 1;
3444 case FFEINFO_basictypeLOGICAL
:
3446 = ffecom_2 (TRUTH_ANDIF_EXPR
, integer_type_node
,
3447 ffecom_truth_value (ffecom_expr (ffebld_left (expr
))),
3448 ffecom_truth_value (ffecom_expr (ffebld_right (expr
))));
3449 return convert (tree_type
, item
);
3451 case FFEINFO_basictypeINTEGER
:
3452 return ffecom_2 (BIT_AND_EXPR
, tree_type
,
3453 ffecom_expr (ffebld_left (expr
)),
3454 ffecom_expr (ffebld_right (expr
)));
3457 assert ("AND bad basictype" == NULL
);
3459 case FFEINFO_basictypeANY
:
3460 return error_mark_node
;
3467 case FFEINFO_basictypeLOGICAL
:
3469 = ffecom_2 (TRUTH_ORIF_EXPR
, integer_type_node
,
3470 ffecom_truth_value (ffecom_expr (ffebld_left (expr
))),
3471 ffecom_truth_value (ffecom_expr (ffebld_right (expr
))));
3472 return convert (tree_type
, item
);
3474 case FFEINFO_basictypeINTEGER
:
3475 return ffecom_2 (BIT_IOR_EXPR
, tree_type
,
3476 ffecom_expr (ffebld_left (expr
)),
3477 ffecom_expr (ffebld_right (expr
)));
3480 assert ("OR bad basictype" == NULL
);
3482 case FFEINFO_basictypeANY
:
3483 return error_mark_node
;
3491 case FFEINFO_basictypeLOGICAL
:
3493 = ffecom_2 (NE_EXPR
, integer_type_node
,
3494 ffecom_expr (ffebld_left (expr
)),
3495 ffecom_expr (ffebld_right (expr
)));
3496 return convert (tree_type
, ffecom_truth_value (item
));
3498 case FFEINFO_basictypeINTEGER
:
3499 return ffecom_2 (BIT_XOR_EXPR
, tree_type
,
3500 ffecom_expr (ffebld_left (expr
)),
3501 ffecom_expr (ffebld_right (expr
)));
3504 assert ("XOR/NEQV bad basictype" == NULL
);
3506 case FFEINFO_basictypeANY
:
3507 return error_mark_node
;
3514 case FFEINFO_basictypeLOGICAL
:
3516 = ffecom_2 (EQ_EXPR
, integer_type_node
,
3517 ffecom_expr (ffebld_left (expr
)),
3518 ffecom_expr (ffebld_right (expr
)));
3519 return convert (tree_type
, ffecom_truth_value (item
));
3521 case FFEINFO_basictypeINTEGER
:
3523 ffecom_1 (BIT_NOT_EXPR
, tree_type
,
3524 ffecom_2 (BIT_XOR_EXPR
, tree_type
,
3525 ffecom_expr (ffebld_left (expr
)),
3526 ffecom_expr (ffebld_right (expr
))));
3529 assert ("EQV bad basictype" == NULL
);
3531 case FFEINFO_basictypeANY
:
3532 return error_mark_node
;
3536 case FFEBLD_opCONVERT
:
3537 if (ffebld_op (ffebld_left (expr
)) == FFEBLD_opANY
)
3538 return error_mark_node
;
3542 case FFEINFO_basictypeLOGICAL
:
3543 case FFEINFO_basictypeINTEGER
:
3544 case FFEINFO_basictypeREAL
:
3545 return convert (tree_type
, ffecom_expr (ffebld_left (expr
)));
3547 case FFEINFO_basictypeCOMPLEX
:
3548 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr
))))
3550 case FFEINFO_basictypeINTEGER
:
3551 case FFEINFO_basictypeLOGICAL
:
3552 case FFEINFO_basictypeREAL
:
3553 item
= ffecom_expr (ffebld_left (expr
));
3554 if (item
== error_mark_node
)
3555 return error_mark_node
;
3556 /* convert() takes care of converting to the subtype first,
3557 at least in gcc-2.7.2. */
3558 item
= convert (tree_type
, item
);
3561 case FFEINFO_basictypeCOMPLEX
:
3562 return convert (tree_type
, ffecom_expr (ffebld_left (expr
)));
3565 assert ("CONVERT COMPLEX bad basictype" == NULL
);
3567 case FFEINFO_basictypeANY
:
3568 return error_mark_node
;
3573 assert ("CONVERT bad basictype" == NULL
);
3575 case FFEINFO_basictypeANY
:
3576 return error_mark_node
;
3582 goto relational
; /* :::::::::::::::::::: */
3586 goto relational
; /* :::::::::::::::::::: */
3590 goto relational
; /* :::::::::::::::::::: */
3594 goto relational
; /* :::::::::::::::::::: */
3598 goto relational
; /* :::::::::::::::::::: */
3603 relational
: /* :::::::::::::::::::: */
3604 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr
))))
3606 case FFEINFO_basictypeLOGICAL
:
3607 case FFEINFO_basictypeINTEGER
:
3608 case FFEINFO_basictypeREAL
:
3609 item
= ffecom_2 (code
, integer_type_node
,
3610 ffecom_expr (ffebld_left (expr
)),
3611 ffecom_expr (ffebld_right (expr
)));
3612 return convert (tree_type
, item
);
3614 case FFEINFO_basictypeCOMPLEX
:
3615 assert (code
== EQ_EXPR
|| code
== NE_EXPR
);
3618 tree arg1
= ffecom_expr (ffebld_left (expr
));
3619 tree arg2
= ffecom_expr (ffebld_right (expr
));
3621 if (arg1
== error_mark_node
|| arg2
== error_mark_node
)
3622 return error_mark_node
;
3624 arg1
= ffecom_save_tree (arg1
);
3625 arg2
= ffecom_save_tree (arg2
);
3627 if (TREE_CODE (TREE_TYPE (arg1
)) == COMPLEX_TYPE
)
3629 real_type
= TREE_TYPE (TREE_TYPE (arg1
));
3630 assert (real_type
== TREE_TYPE (TREE_TYPE (arg2
)));
3634 real_type
= TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1
)));
3635 assert (real_type
== TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2
))));
3639 = ffecom_2 (TRUTH_ANDIF_EXPR
, integer_type_node
,
3640 ffecom_2 (EQ_EXPR
, integer_type_node
,
3641 ffecom_1 (REALPART_EXPR
, real_type
, arg1
),
3642 ffecom_1 (REALPART_EXPR
, real_type
, arg2
)),
3643 ffecom_2 (EQ_EXPR
, integer_type_node
,
3644 ffecom_1 (IMAGPART_EXPR
, real_type
, arg1
),
3645 ffecom_1 (IMAGPART_EXPR
, real_type
,
3647 if (code
== EQ_EXPR
)
3648 item
= ffecom_truth_value (item
);
3650 item
= ffecom_truth_value_invert (item
);
3651 return convert (tree_type
, item
);
3654 case FFEINFO_basictypeCHARACTER
:
3656 ffebld left
= ffebld_left (expr
);
3657 ffebld right
= ffebld_right (expr
);
3663 /* f2c run-time functions do the implicit blank-padding for us,
3664 so we don't usually have to implement blank-padding ourselves.
3665 (The exception is when we pass an argument to a separately
3666 compiled statement function -- if we know the arg is not the
3667 same length as the dummy, we must truncate or extend it. If
3668 we "inline" statement functions, that necessity goes away as
3671 Strip off the CONVERT operators that blank-pad. (Truncation by
3672 CONVERT shouldn't happen here, but it can happen in
3675 while (ffebld_op (left
) == FFEBLD_opCONVERT
)
3676 left
= ffebld_left (left
);
3677 while (ffebld_op (right
) == FFEBLD_opCONVERT
)
3678 right
= ffebld_left (right
);
3680 left_tree
= ffecom_arg_ptr_to_expr (left
, &left_length
);
3681 right_tree
= ffecom_arg_ptr_to_expr (right
, &right_length
);
3683 if (left_tree
== error_mark_node
|| left_length
== error_mark_node
3684 || right_tree
== error_mark_node
3685 || right_length
== error_mark_node
)
3686 return error_mark_node
;
3688 if ((ffebld_size_known (left
) == 1)
3689 && (ffebld_size_known (right
) == 1))
3692 = ffecom_1 (INDIRECT_REF
,
3693 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree
))),
3696 = ffecom_1 (INDIRECT_REF
,
3697 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree
))),
3701 = ffecom_2 (code
, integer_type_node
,
3702 ffecom_2 (ARRAY_REF
,
3703 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree
))),
3706 ffecom_2 (ARRAY_REF
,
3707 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree
))),
3713 item
= build_tree_list (NULL_TREE
, left_tree
);
3714 TREE_CHAIN (item
) = build_tree_list (NULL_TREE
, right_tree
);
3715 TREE_CHAIN (TREE_CHAIN (item
)) = build_tree_list (NULL_TREE
,
3717 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item
)))
3718 = build_tree_list (NULL_TREE
, right_length
);
3719 item
= ffecom_call_gfrt (FFECOM_gfrtCMP
, item
, NULL_TREE
);
3720 item
= ffecom_2 (code
, integer_type_node
,
3722 convert (TREE_TYPE (item
),
3723 integer_zero_node
));
3725 item
= convert (tree_type
, item
);
3731 assert ("relational bad basictype" == NULL
);
3733 case FFEINFO_basictypeANY
:
3734 return error_mark_node
;
3738 case FFEBLD_opPERCENT_LOC
:
3739 item
= ffecom_arg_ptr_to_expr (ffebld_left (expr
), &list
);
3740 return convert (tree_type
, item
);
3742 case FFEBLD_opPERCENT_VAL
:
3743 item
= ffecom_arg_expr (ffebld_left (expr
), &list
);
3744 return convert (tree_type
, item
);
3748 case FFEBLD_opBOUNDS
:
3749 case FFEBLD_opREPEAT
:
3750 case FFEBLD_opLABTER
:
3751 case FFEBLD_opLABTOK
:
3752 case FFEBLD_opIMPDO
:
3753 case FFEBLD_opCONCATENATE
:
3754 case FFEBLD_opSUBSTR
:
3756 assert ("bad op" == NULL
);
3759 return error_mark_node
;
3763 assert ("didn't think anything got here anymore!!" == NULL
);
3765 switch (ffebld_arity (expr
))
3768 TREE_OPERAND (item
, 0) = ffecom_expr (ffebld_left (expr
));
3769 TREE_OPERAND (item
, 1) = ffecom_expr (ffebld_right (expr
));
3770 if (TREE_OPERAND (item
, 0) == error_mark_node
3771 || TREE_OPERAND (item
, 1) == error_mark_node
)
3772 return error_mark_node
;
3776 TREE_OPERAND (item
, 0) = ffecom_expr (ffebld_left (expr
));
3777 if (TREE_OPERAND (item
, 0) == error_mark_node
)
3778 return error_mark_node
;
3789 /* Returns the tree that does the intrinsic invocation.
3791 Note: this function applies only to intrinsics returning
3792 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3796 ffecom_expr_intrinsic_ (ffebld expr
, tree dest_tree
, ffebld dest
,
3800 tree saved_expr1
; /* For those who need it. */
3801 tree saved_expr2
; /* For those who need it. */
3802 ffeinfoBasictype bt
;
3806 tree real_type
; /* REAL type corresponding to COMPLEX. */
3808 ffebld list
= ffebld_right (expr
); /* List of (some) args. */
3809 ffebld arg1
; /* For handy reference. */
3812 ffeintrinImp codegen_imp
;
3815 assert (ffebld_op (ffebld_left (expr
)) == FFEBLD_opSYMTER
);
3817 if (dest_used
!= NULL
)
3820 bt
= ffeinfo_basictype (ffebld_info (expr
));
3821 kt
= ffeinfo_kindtype (ffebld_info (expr
));
3822 tree_type
= ffecom_tree_type
[bt
][kt
];
3826 arg1
= ffebld_head (list
);
3827 if (arg1
!= NULL
&& ffebld_op (arg1
) == FFEBLD_opANY
)
3828 return error_mark_node
;
3829 if ((list
= ffebld_trail (list
)) != NULL
)
3831 arg2
= ffebld_head (list
);
3832 if (arg2
!= NULL
&& ffebld_op (arg2
) == FFEBLD_opANY
)
3833 return error_mark_node
;
3834 if ((list
= ffebld_trail (list
)) != NULL
)
3836 arg3
= ffebld_head (list
);
3837 if (arg3
!= NULL
&& ffebld_op (arg3
) == FFEBLD_opANY
)
3838 return error_mark_node
;
3847 arg1
= arg2
= arg3
= NULL
;
3849 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3850 args. This is used by the MAX/MIN expansions. */
3853 arg1_type
= ffecom_tree_type
3854 [ffeinfo_basictype (ffebld_info (arg1
))]
3855 [ffeinfo_kindtype (ffebld_info (arg1
))];
3857 arg1_type
= NULL_TREE
; /* Really not needed, but might catch bugs
3860 /* There are several ways for each of the cases in the following switch
3861 statements to exit (from simplest to use to most complicated):
3863 break; (when expr_tree == NULL)
3865 A standard call is made to the specific intrinsic just as if it had been
3866 passed in as a dummy procedure and called as any old procedure. This
3867 method can produce slower code but in some cases it's the easiest way for
3868 now. However, if a (presumably faster) direct call is available,
3869 that is used, so this is the easiest way in many more cases now.
3871 gfrt = FFECOM_gfrtWHATEVER;
3874 gfrt contains the gfrt index of a library function to call, passing the
3875 argument(s) by value rather than by reference. Used when a more
3876 careful choice of library function is needed than that provided
3877 by the vanilla `break;'.
3881 The expr_tree has been completely set up and is ready to be returned
3882 as is. No further actions are taken. Use this when the tree is not
3883 in the simple form for one of the arity_n labels. */
3885 /* For info on how the switch statement cases were written, see the files
3886 enclosed in comments below the switch statement. */
3888 codegen_imp
= ffebld_symter_implementation (ffebld_left (expr
));
3889 gfrt
= ffeintrin_gfrt_direct (codegen_imp
);
3890 if (gfrt
== FFECOM_gfrt
)
3891 gfrt
= ffeintrin_gfrt_indirect (codegen_imp
);
3893 switch (codegen_imp
)
3895 case FFEINTRIN_impABS
:
3896 case FFEINTRIN_impCABS
:
3897 case FFEINTRIN_impCDABS
:
3898 case FFEINTRIN_impDABS
:
3899 case FFEINTRIN_impIABS
:
3900 if (ffeinfo_basictype (ffebld_info (arg1
))
3901 == FFEINFO_basictypeCOMPLEX
)
3903 if (kt
== FFEINFO_kindtypeREAL1
)
3904 gfrt
= FFECOM_gfrtCABS
;
3905 else if (kt
== FFEINFO_kindtypeREAL2
)
3906 gfrt
= FFECOM_gfrtCDABS
;
3909 return ffecom_1 (ABS_EXPR
, tree_type
,
3910 convert (tree_type
, ffecom_expr (arg1
)));
3912 case FFEINTRIN_impACOS
:
3913 case FFEINTRIN_impDACOS
:
3916 case FFEINTRIN_impAIMAG
:
3917 case FFEINTRIN_impDIMAG
:
3918 case FFEINTRIN_impIMAGPART
:
3919 if (TREE_CODE (arg1_type
) == COMPLEX_TYPE
)
3920 arg1_type
= TREE_TYPE (arg1_type
);
3922 arg1_type
= TREE_TYPE (TYPE_FIELDS (arg1_type
));
3926 ffecom_1 (IMAGPART_EXPR
, arg1_type
,
3927 ffecom_expr (arg1
)));
3929 case FFEINTRIN_impAINT
:
3930 case FFEINTRIN_impDINT
:
3932 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
3933 return ffecom_1 (FIX_TRUNC_EXPR
, tree_type
, ffecom_expr (arg1
));
3934 #else /* in the meantime, must use floor to avoid range problems with ints */
3935 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
3936 saved_expr1
= ffecom_save_tree (ffecom_expr (arg1
));
3939 ffecom_3 (COND_EXPR
, double_type_node
,
3941 (ffecom_2 (GE_EXPR
, integer_type_node
,
3944 ffecom_float_zero_
))),
3945 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR
,
3946 build_tree_list (NULL_TREE
,
3947 convert (double_type_node
,
3950 ffecom_1 (NEGATE_EXPR
, double_type_node
,
3951 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR
,
3952 build_tree_list (NULL_TREE
,
3953 convert (double_type_node
,
3954 ffecom_1 (NEGATE_EXPR
,
3962 case FFEINTRIN_impANINT
:
3963 case FFEINTRIN_impDNINT
:
3964 #if 0 /* This way of doing it won't handle real
3965 numbers of large magnitudes. */
3966 saved_expr1
= ffecom_save_tree (ffecom_expr (arg1
));
3967 expr_tree
= convert (tree_type
,
3968 convert (integer_type_node
,
3969 ffecom_3 (COND_EXPR
, tree_type
,
3974 ffecom_float_zero_
)),
3975 ffecom_2 (PLUS_EXPR
,
3978 ffecom_float_half_
),
3979 ffecom_2 (MINUS_EXPR
,
3982 ffecom_float_half_
))));
3984 #else /* So we instead call floor. */
3985 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
3986 saved_expr1
= ffecom_save_tree (ffecom_expr (arg1
));
3989 ffecom_3 (COND_EXPR
, double_type_node
,
3991 (ffecom_2 (GE_EXPR
, integer_type_node
,
3994 ffecom_float_zero_
))),
3995 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR
,
3996 build_tree_list (NULL_TREE
,
3997 convert (double_type_node
,
3998 ffecom_2 (PLUS_EXPR
,
4002 ffecom_float_half_
)))),
4004 ffecom_1 (NEGATE_EXPR
, double_type_node
,
4005 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR
,
4006 build_tree_list (NULL_TREE
,
4007 convert (double_type_node
,
4008 ffecom_2 (MINUS_EXPR
,
4011 ffecom_float_half_
),
4018 case FFEINTRIN_impASIN
:
4019 case FFEINTRIN_impDASIN
:
4020 case FFEINTRIN_impATAN
:
4021 case FFEINTRIN_impDATAN
:
4022 case FFEINTRIN_impATAN2
:
4023 case FFEINTRIN_impDATAN2
:
4026 case FFEINTRIN_impCHAR
:
4027 case FFEINTRIN_impACHAR
:
4028 tempvar
= ffebld_nonter_hook (expr
);
4031 tree tmv
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar
)));
4033 expr_tree
= ffecom_modify (tmv
,
4034 ffecom_2 (ARRAY_REF
, tmv
, tempvar
,
4036 convert (tmv
, ffecom_expr (arg1
)));
4038 expr_tree
= ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (tempvar
),
4041 expr_tree
= ffecom_1 (ADDR_EXPR
,
4042 build_pointer_type (TREE_TYPE (expr_tree
)),
4046 case FFEINTRIN_impCMPLX
:
4047 case FFEINTRIN_impDCMPLX
:
4050 convert (tree_type
, ffecom_expr (arg1
));
4052 real_type
= ffecom_tree_type
[FFEINFO_basictypeREAL
][kt
];
4054 ffecom_2 (COMPLEX_EXPR
, tree_type
,
4055 convert (real_type
, ffecom_expr (arg1
)),
4057 ffecom_expr (arg2
)));
4059 case FFEINTRIN_impCOMPLEX
:
4061 ffecom_2 (COMPLEX_EXPR
, tree_type
,
4063 ffecom_expr (arg2
));
4065 case FFEINTRIN_impCONJG
:
4066 case FFEINTRIN_impDCONJG
:
4070 real_type
= ffecom_tree_type
[FFEINFO_basictypeREAL
][kt
];
4071 arg1_tree
= ffecom_save_tree (ffecom_expr (arg1
));
4073 ffecom_2 (COMPLEX_EXPR
, tree_type
,
4074 ffecom_1 (REALPART_EXPR
, real_type
, arg1_tree
),
4075 ffecom_1 (NEGATE_EXPR
, real_type
,
4076 ffecom_1 (IMAGPART_EXPR
, real_type
, arg1_tree
)));
4079 case FFEINTRIN_impCOS
:
4080 case FFEINTRIN_impCCOS
:
4081 case FFEINTRIN_impCDCOS
:
4082 case FFEINTRIN_impDCOS
:
4083 if (bt
== FFEINFO_basictypeCOMPLEX
)
4085 if (kt
== FFEINFO_kindtypeREAL1
)
4086 gfrt
= FFECOM_gfrtCCOS
; /* Overlapping result okay. */
4087 else if (kt
== FFEINFO_kindtypeREAL2
)
4088 gfrt
= FFECOM_gfrtCDCOS
; /* Overlapping result okay. */
4092 case FFEINTRIN_impCOSH
:
4093 case FFEINTRIN_impDCOSH
:
4096 case FFEINTRIN_impDBLE
:
4097 case FFEINTRIN_impDFLOAT
:
4098 case FFEINTRIN_impDREAL
:
4099 case FFEINTRIN_impFLOAT
:
4100 case FFEINTRIN_impIDINT
:
4101 case FFEINTRIN_impIFIX
:
4102 case FFEINTRIN_impINT2
:
4103 case FFEINTRIN_impINT8
:
4104 case FFEINTRIN_impINT
:
4105 case FFEINTRIN_impLONG
:
4106 case FFEINTRIN_impREAL
:
4107 case FFEINTRIN_impSHORT
:
4108 case FFEINTRIN_impSNGL
:
4109 return convert (tree_type
, ffecom_expr (arg1
));
4111 case FFEINTRIN_impDIM
:
4112 case FFEINTRIN_impDDIM
:
4113 case FFEINTRIN_impIDIM
:
4114 saved_expr1
= ffecom_save_tree (convert (tree_type
,
4115 ffecom_expr (arg1
)));
4116 saved_expr2
= ffecom_save_tree (convert (tree_type
,
4117 ffecom_expr (arg2
)));
4119 ffecom_3 (COND_EXPR
, tree_type
,
4121 (ffecom_2 (GT_EXPR
, integer_type_node
,
4124 ffecom_2 (MINUS_EXPR
, tree_type
,
4127 convert (tree_type
, ffecom_float_zero_
));
4129 case FFEINTRIN_impDPROD
:
4131 ffecom_2 (MULT_EXPR
, tree_type
,
4132 convert (tree_type
, ffecom_expr (arg1
)),
4133 convert (tree_type
, ffecom_expr (arg2
)));
4135 case FFEINTRIN_impEXP
:
4136 case FFEINTRIN_impCDEXP
:
4137 case FFEINTRIN_impCEXP
:
4138 case FFEINTRIN_impDEXP
:
4139 if (bt
== FFEINFO_basictypeCOMPLEX
)
4141 if (kt
== FFEINFO_kindtypeREAL1
)
4142 gfrt
= FFECOM_gfrtCEXP
; /* Overlapping result okay. */
4143 else if (kt
== FFEINFO_kindtypeREAL2
)
4144 gfrt
= FFECOM_gfrtCDEXP
; /* Overlapping result okay. */
4148 case FFEINTRIN_impICHAR
:
4149 case FFEINTRIN_impIACHAR
:
4150 #if 0 /* The simple approach. */
4151 ffecom_char_args_ (&expr_tree
, &saved_expr1
/* Ignored */ , arg1
);
4153 = ffecom_1 (INDIRECT_REF
,
4154 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree
))),
4157 = ffecom_2 (ARRAY_REF
,
4158 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree
))),
4161 return convert (tree_type
, expr_tree
);
4162 #else /* The more interesting (and more optimal) approach. */
4163 expr_tree
= ffecom_intrinsic_ichar_ (tree_type
, arg1
, &saved_expr1
);
4164 expr_tree
= ffecom_3 (COND_EXPR
, tree_type
,
4167 convert (tree_type
, integer_zero_node
));
4171 case FFEINTRIN_impINDEX
:
4174 case FFEINTRIN_impLEN
:
4176 break; /* The simple approach. */
4178 return ffecom_intrinsic_len_ (arg1
); /* The more optimal approach. */
4181 case FFEINTRIN_impLGE
:
4182 case FFEINTRIN_impLGT
:
4183 case FFEINTRIN_impLLE
:
4184 case FFEINTRIN_impLLT
:
4187 case FFEINTRIN_impLOG
:
4188 case FFEINTRIN_impALOG
:
4189 case FFEINTRIN_impCDLOG
:
4190 case FFEINTRIN_impCLOG
:
4191 case FFEINTRIN_impDLOG
:
4192 if (bt
== FFEINFO_basictypeCOMPLEX
)
4194 if (kt
== FFEINFO_kindtypeREAL1
)
4195 gfrt
= FFECOM_gfrtCLOG
; /* Overlapping result okay. */
4196 else if (kt
== FFEINFO_kindtypeREAL2
)
4197 gfrt
= FFECOM_gfrtCDLOG
; /* Overlapping result okay. */
4201 case FFEINTRIN_impLOG10
:
4202 case FFEINTRIN_impALOG10
:
4203 case FFEINTRIN_impDLOG10
:
4204 if (gfrt
!= FFECOM_gfrt
)
4205 break; /* Already picked one, stick with it. */
4207 if (kt
== FFEINFO_kindtypeREAL1
)
4208 /* We used to call FFECOM_gfrtALOG10 here. */
4209 gfrt
= FFECOM_gfrtL_LOG10
;
4210 else if (kt
== FFEINFO_kindtypeREAL2
)
4211 /* We used to call FFECOM_gfrtDLOG10 here. */
4212 gfrt
= FFECOM_gfrtL_LOG10
;
4215 case FFEINTRIN_impMAX
:
4216 case FFEINTRIN_impAMAX0
:
4217 case FFEINTRIN_impAMAX1
:
4218 case FFEINTRIN_impDMAX1
:
4219 case FFEINTRIN_impMAX0
:
4220 case FFEINTRIN_impMAX1
:
4221 if (bt
!= ffeinfo_basictype (ffebld_info (arg1
)))
4222 arg1_type
= ffecom_widest_expr_type_ (ffebld_right (expr
));
4224 arg1_type
= tree_type
;
4225 expr_tree
= ffecom_2 (MAX_EXPR
, arg1_type
,
4226 convert (arg1_type
, ffecom_expr (arg1
)),
4227 convert (arg1_type
, ffecom_expr (arg2
)));
4228 for (; list
!= NULL
; list
= ffebld_trail (list
))
4230 if ((ffebld_head (list
) == NULL
)
4231 || (ffebld_op (ffebld_head (list
)) == FFEBLD_opANY
))
4233 expr_tree
= ffecom_2 (MAX_EXPR
, arg1_type
,
4236 ffecom_expr (ffebld_head (list
))));
4238 return convert (tree_type
, expr_tree
);
4240 case FFEINTRIN_impMIN
:
4241 case FFEINTRIN_impAMIN0
:
4242 case FFEINTRIN_impAMIN1
:
4243 case FFEINTRIN_impDMIN1
:
4244 case FFEINTRIN_impMIN0
:
4245 case FFEINTRIN_impMIN1
:
4246 if (bt
!= ffeinfo_basictype (ffebld_info (arg1
)))
4247 arg1_type
= ffecom_widest_expr_type_ (ffebld_right (expr
));
4249 arg1_type
= tree_type
;
4250 expr_tree
= ffecom_2 (MIN_EXPR
, arg1_type
,
4251 convert (arg1_type
, ffecom_expr (arg1
)),
4252 convert (arg1_type
, ffecom_expr (arg2
)));
4253 for (; list
!= NULL
; list
= ffebld_trail (list
))
4255 if ((ffebld_head (list
) == NULL
)
4256 || (ffebld_op (ffebld_head (list
)) == FFEBLD_opANY
))
4258 expr_tree
= ffecom_2 (MIN_EXPR
, arg1_type
,
4261 ffecom_expr (ffebld_head (list
))));
4263 return convert (tree_type
, expr_tree
);
4265 case FFEINTRIN_impMOD
:
4266 case FFEINTRIN_impAMOD
:
4267 case FFEINTRIN_impDMOD
:
4268 if (bt
!= FFEINFO_basictypeREAL
)
4269 return ffecom_2 (TRUNC_MOD_EXPR
, tree_type
,
4270 convert (tree_type
, ffecom_expr (arg1
)),
4271 convert (tree_type
, ffecom_expr (arg2
)));
4273 if (kt
== FFEINFO_kindtypeREAL1
)
4274 /* We used to call FFECOM_gfrtAMOD here. */
4275 gfrt
= FFECOM_gfrtL_FMOD
;
4276 else if (kt
== FFEINFO_kindtypeREAL2
)
4277 /* We used to call FFECOM_gfrtDMOD here. */
4278 gfrt
= FFECOM_gfrtL_FMOD
;
4281 case FFEINTRIN_impNINT
:
4282 case FFEINTRIN_impIDNINT
:
4284 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
4285 return ffecom_1 (FIX_ROUND_EXPR
, tree_type
, ffecom_expr (arg1
));
4287 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4288 saved_expr1
= ffecom_save_tree (ffecom_expr (arg1
));
4290 convert (ffecom_integer_type_node
,
4291 ffecom_3 (COND_EXPR
, arg1_type
,
4293 (ffecom_2 (GE_EXPR
, integer_type_node
,
4296 ffecom_float_zero_
))),
4297 ffecom_2 (PLUS_EXPR
, arg1_type
,
4300 ffecom_float_half_
)),
4301 ffecom_2 (MINUS_EXPR
, arg1_type
,
4304 ffecom_float_half_
))));
4307 case FFEINTRIN_impSIGN
:
4308 case FFEINTRIN_impDSIGN
:
4309 case FFEINTRIN_impISIGN
:
4311 tree arg2_tree
= ffecom_expr (arg2
);
4315 (ffecom_1 (ABS_EXPR
, tree_type
,
4317 ffecom_expr (arg1
))));
4319 = ffecom_3 (COND_EXPR
, tree_type
,
4321 (ffecom_2 (GE_EXPR
, integer_type_node
,
4323 convert (TREE_TYPE (arg2_tree
),
4324 integer_zero_node
))),
4326 ffecom_1 (NEGATE_EXPR
, tree_type
, saved_expr1
));
4327 /* Make sure SAVE_EXPRs get referenced early enough. */
4329 = ffecom_2 (COMPOUND_EXPR
, tree_type
,
4330 convert (void_type_node
, saved_expr1
),
4335 case FFEINTRIN_impSIN
:
4336 case FFEINTRIN_impCDSIN
:
4337 case FFEINTRIN_impCSIN
:
4338 case FFEINTRIN_impDSIN
:
4339 if (bt
== FFEINFO_basictypeCOMPLEX
)
4341 if (kt
== FFEINFO_kindtypeREAL1
)
4342 gfrt
= FFECOM_gfrtCSIN
; /* Overlapping result okay. */
4343 else if (kt
== FFEINFO_kindtypeREAL2
)
4344 gfrt
= FFECOM_gfrtCDSIN
; /* Overlapping result okay. */
4348 case FFEINTRIN_impSINH
:
4349 case FFEINTRIN_impDSINH
:
4352 case FFEINTRIN_impSQRT
:
4353 case FFEINTRIN_impCDSQRT
:
4354 case FFEINTRIN_impCSQRT
:
4355 case FFEINTRIN_impDSQRT
:
4356 if (bt
== FFEINFO_basictypeCOMPLEX
)
4358 if (kt
== FFEINFO_kindtypeREAL1
)
4359 gfrt
= FFECOM_gfrtCSQRT
; /* Overlapping result okay. */
4360 else if (kt
== FFEINFO_kindtypeREAL2
)
4361 gfrt
= FFECOM_gfrtCDSQRT
; /* Overlapping result okay. */
4365 case FFEINTRIN_impTAN
:
4366 case FFEINTRIN_impDTAN
:
4367 case FFEINTRIN_impTANH
:
4368 case FFEINTRIN_impDTANH
:
4371 case FFEINTRIN_impREALPART
:
4372 if (TREE_CODE (arg1_type
) == COMPLEX_TYPE
)
4373 arg1_type
= TREE_TYPE (arg1_type
);
4375 arg1_type
= TREE_TYPE (TYPE_FIELDS (arg1_type
));
4379 ffecom_1 (REALPART_EXPR
, arg1_type
,
4380 ffecom_expr (arg1
)));
4382 case FFEINTRIN_impIAND
:
4383 case FFEINTRIN_impAND
:
4384 return ffecom_2 (BIT_AND_EXPR
, tree_type
,
4386 ffecom_expr (arg1
)),
4388 ffecom_expr (arg2
)));
4390 case FFEINTRIN_impIOR
:
4391 case FFEINTRIN_impOR
:
4392 return ffecom_2 (BIT_IOR_EXPR
, tree_type
,
4394 ffecom_expr (arg1
)),
4396 ffecom_expr (arg2
)));
4398 case FFEINTRIN_impIEOR
:
4399 case FFEINTRIN_impXOR
:
4400 return ffecom_2 (BIT_XOR_EXPR
, tree_type
,
4402 ffecom_expr (arg1
)),
4404 ffecom_expr (arg2
)));
4406 case FFEINTRIN_impLSHIFT
:
4407 return ffecom_2 (LSHIFT_EXPR
, tree_type
,
4409 convert (integer_type_node
,
4410 ffecom_expr (arg2
)));
4412 case FFEINTRIN_impRSHIFT
:
4413 return ffecom_2 (RSHIFT_EXPR
, tree_type
,
4415 convert (integer_type_node
,
4416 ffecom_expr (arg2
)));
4418 case FFEINTRIN_impNOT
:
4419 return ffecom_1 (BIT_NOT_EXPR
, tree_type
, ffecom_expr (arg1
));
4421 case FFEINTRIN_impBIT_SIZE
:
4422 return convert (tree_type
, TYPE_SIZE (arg1_type
));
4424 case FFEINTRIN_impBTEST
:
4426 ffetargetLogical1 target_true
;
4427 ffetargetLogical1 target_false
;
4431 ffetarget_logical1 (&target_true
, TRUE
);
4432 ffetarget_logical1 (&target_false
, FALSE
);
4433 if (target_true
== 1)
4434 true_tree
= convert (tree_type
, integer_one_node
);
4436 true_tree
= convert (tree_type
, build_int_2 (target_true
, 0));
4437 if (target_false
== 0)
4438 false_tree
= convert (tree_type
, integer_zero_node
);
4440 false_tree
= convert (tree_type
, build_int_2 (target_false
, 0));
4443 ffecom_3 (COND_EXPR
, tree_type
,
4445 (ffecom_2 (EQ_EXPR
, integer_type_node
,
4446 ffecom_2 (BIT_AND_EXPR
, arg1_type
,
4448 ffecom_2 (LSHIFT_EXPR
, arg1_type
,
4451 convert (integer_type_node
,
4452 ffecom_expr (arg2
)))),
4454 integer_zero_node
))),
4459 case FFEINTRIN_impIBCLR
:
4461 ffecom_2 (BIT_AND_EXPR
, tree_type
,
4463 ffecom_1 (BIT_NOT_EXPR
, tree_type
,
4464 ffecom_2 (LSHIFT_EXPR
, tree_type
,
4467 convert (integer_type_node
,
4468 ffecom_expr (arg2
)))));
4470 case FFEINTRIN_impIBITS
:
4472 tree arg3_tree
= ffecom_save_tree (convert (integer_type_node
,
4473 ffecom_expr (arg3
)));
4475 = ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][kt
];
4478 = ffecom_2 (BIT_AND_EXPR
, tree_type
,
4479 ffecom_2 (RSHIFT_EXPR
, tree_type
,
4481 convert (integer_type_node
,
4482 ffecom_expr (arg2
))),
4484 ffecom_2 (RSHIFT_EXPR
, uns_type
,
4485 ffecom_1 (BIT_NOT_EXPR
,
4488 integer_zero_node
)),
4489 ffecom_2 (MINUS_EXPR
,
4491 TYPE_SIZE (uns_type
),
4493 /* Fix up, because the RSHIFT_EXPR above can't shift over TYPE_SIZE. */
4495 = ffecom_3 (COND_EXPR
, tree_type
,
4497 (ffecom_2 (NE_EXPR
, integer_type_node
,
4499 integer_zero_node
)),
4501 convert (tree_type
, integer_zero_node
));
4505 case FFEINTRIN_impIBSET
:
4507 ffecom_2 (BIT_IOR_EXPR
, tree_type
,
4509 ffecom_2 (LSHIFT_EXPR
, tree_type
,
4510 convert (tree_type
, integer_one_node
),
4511 convert (integer_type_node
,
4512 ffecom_expr (arg2
))));
4514 case FFEINTRIN_impISHFT
:
4516 tree arg1_tree
= ffecom_save_tree (ffecom_expr (arg1
));
4517 tree arg2_tree
= ffecom_save_tree (convert (integer_type_node
,
4518 ffecom_expr (arg2
)));
4520 = ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][kt
];
4523 = ffecom_3 (COND_EXPR
, tree_type
,
4525 (ffecom_2 (GE_EXPR
, integer_type_node
,
4527 integer_zero_node
)),
4528 ffecom_2 (LSHIFT_EXPR
, tree_type
,
4532 ffecom_2 (RSHIFT_EXPR
, uns_type
,
4533 convert (uns_type
, arg1_tree
),
4534 ffecom_1 (NEGATE_EXPR
,
4537 /* Fix up, because {L|R}SHIFT_EXPR don't go over TYPE_SIZE bounds. */
4539 = ffecom_3 (COND_EXPR
, tree_type
,
4541 (ffecom_2 (NE_EXPR
, integer_type_node
,
4545 TYPE_SIZE (uns_type
))),
4547 convert (tree_type
, integer_zero_node
));
4548 /* Make sure SAVE_EXPRs get referenced early enough. */
4550 = ffecom_2 (COMPOUND_EXPR
, tree_type
,
4551 convert (void_type_node
, arg1_tree
),
4552 ffecom_2 (COMPOUND_EXPR
, tree_type
,
4553 convert (void_type_node
, arg2_tree
),
4558 case FFEINTRIN_impISHFTC
:
4560 tree arg1_tree
= ffecom_save_tree (ffecom_expr (arg1
));
4561 tree arg2_tree
= ffecom_save_tree (convert (integer_type_node
,
4562 ffecom_expr (arg2
)));
4563 tree arg3_tree
= (arg3
== NULL
) ? TYPE_SIZE (tree_type
)
4564 : ffecom_save_tree (convert (integer_type_node
, ffecom_expr (arg3
)));
4570 = ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][kt
];
4573 = ffecom_2 (LSHIFT_EXPR
, tree_type
,
4574 ffecom_1 (BIT_NOT_EXPR
, tree_type
,
4575 convert (tree_type
, integer_zero_node
)),
4577 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
4579 = ffecom_3 (COND_EXPR
, tree_type
,
4581 (ffecom_2 (NE_EXPR
, integer_type_node
,
4583 TYPE_SIZE (uns_type
))),
4585 convert (tree_type
, integer_zero_node
));
4586 mask_arg1
= ffecom_save_tree (mask_arg1
);
4588 = ffecom_2 (BIT_AND_EXPR
, tree_type
,
4590 ffecom_1 (BIT_NOT_EXPR
, tree_type
,
4592 masked_arg1
= ffecom_save_tree (masked_arg1
);
4594 = ffecom_2 (BIT_IOR_EXPR
, tree_type
,
4596 ffecom_2 (RSHIFT_EXPR
, uns_type
,
4597 convert (uns_type
, masked_arg1
),
4598 ffecom_1 (NEGATE_EXPR
,
4601 ffecom_2 (LSHIFT_EXPR
, tree_type
,
4603 ffecom_2 (PLUS_EXPR
, integer_type_node
,
4607 = ffecom_2 (BIT_IOR_EXPR
, tree_type
,
4608 ffecom_2 (LSHIFT_EXPR
, tree_type
,
4612 ffecom_2 (RSHIFT_EXPR
, uns_type
,
4613 convert (uns_type
, masked_arg1
),
4614 ffecom_2 (MINUS_EXPR
,
4619 = ffecom_3 (COND_EXPR
, tree_type
,
4621 (ffecom_2 (LT_EXPR
, integer_type_node
,
4623 integer_zero_node
)),
4627 = ffecom_2 (BIT_IOR_EXPR
, tree_type
,
4628 ffecom_2 (BIT_AND_EXPR
, tree_type
,
4631 ffecom_2 (BIT_AND_EXPR
, tree_type
,
4632 ffecom_1 (BIT_NOT_EXPR
, tree_type
,
4636 = ffecom_3 (COND_EXPR
, tree_type
,
4638 (ffecom_2 (TRUTH_ORIF_EXPR
, integer_type_node
,
4639 ffecom_2 (EQ_EXPR
, integer_type_node
,
4644 ffecom_2 (EQ_EXPR
, integer_type_node
,
4646 integer_zero_node
))),
4649 /* Make sure SAVE_EXPRs get referenced early enough. */
4651 = ffecom_2 (COMPOUND_EXPR
, tree_type
,
4652 convert (void_type_node
, arg1_tree
),
4653 ffecom_2 (COMPOUND_EXPR
, tree_type
,
4654 convert (void_type_node
, arg2_tree
),
4655 ffecom_2 (COMPOUND_EXPR
, tree_type
,
4656 convert (void_type_node
,
4658 ffecom_2 (COMPOUND_EXPR
, tree_type
,
4659 convert (void_type_node
,
4663 = ffecom_2 (COMPOUND_EXPR
, tree_type
,
4664 convert (void_type_node
,
4670 case FFEINTRIN_impLOC
:
4672 tree arg1_tree
= ffecom_expr (arg1
);
4675 = convert (tree_type
,
4676 ffecom_1 (ADDR_EXPR
,
4677 build_pointer_type (TREE_TYPE (arg1_tree
)),
4682 case FFEINTRIN_impMVBITS
:
4687 ffebld arg4
= ffebld_head (ffebld_trail (list
));
4690 ffebld arg5
= ffebld_head (ffebld_trail (ffebld_trail (list
)));
4694 tree arg5_plus_arg3
;
4696 arg2_tree
= convert (integer_type_node
,
4697 ffecom_expr (arg2
));
4698 arg3_tree
= ffecom_save_tree (convert (integer_type_node
,
4699 ffecom_expr (arg3
)));
4700 arg4_tree
= ffecom_expr_rw (NULL_TREE
, arg4
);
4701 arg4_type
= TREE_TYPE (arg4_tree
);
4703 arg1_tree
= ffecom_save_tree (convert (arg4_type
,
4704 ffecom_expr (arg1
)));
4706 arg5_tree
= ffecom_save_tree (convert (integer_type_node
,
4707 ffecom_expr (arg5
)));
4710 = ffecom_2 (LSHIFT_EXPR
, arg4_type
,
4711 ffecom_2 (BIT_AND_EXPR
, arg4_type
,
4712 ffecom_2 (RSHIFT_EXPR
, arg4_type
,
4715 ffecom_1 (BIT_NOT_EXPR
, arg4_type
,
4716 ffecom_2 (LSHIFT_EXPR
, arg4_type
,
4717 ffecom_1 (BIT_NOT_EXPR
,
4721 integer_zero_node
)),
4725 = ffecom_save_tree (ffecom_2 (PLUS_EXPR
, arg4_type
,
4729 = ffecom_2 (LSHIFT_EXPR
, arg4_type
,
4730 ffecom_1 (BIT_NOT_EXPR
, arg4_type
,
4732 integer_zero_node
)),
4734 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
4736 = ffecom_3 (COND_EXPR
, arg4_type
,
4738 (ffecom_2 (NE_EXPR
, integer_type_node
,
4740 convert (TREE_TYPE (arg5_plus_arg3
),
4741 TYPE_SIZE (arg4_type
)))),
4743 convert (arg4_type
, integer_zero_node
));
4745 = ffecom_2 (BIT_AND_EXPR
, arg4_type
,
4747 ffecom_2 (BIT_IOR_EXPR
, arg4_type
,
4749 ffecom_1 (BIT_NOT_EXPR
, arg4_type
,
4750 ffecom_2 (LSHIFT_EXPR
, arg4_type
,
4751 ffecom_1 (BIT_NOT_EXPR
,
4755 integer_zero_node
)),
4758 = ffecom_2 (BIT_IOR_EXPR
, arg4_type
,
4761 /* Fix up (twice), because LSHIFT_EXPR above
4762 can't shift over TYPE_SIZE. */
4764 = ffecom_3 (COND_EXPR
, arg4_type
,
4766 (ffecom_2 (NE_EXPR
, integer_type_node
,
4768 convert (TREE_TYPE (arg3_tree
),
4769 integer_zero_node
))),
4773 = ffecom_3 (COND_EXPR
, arg4_type
,
4775 (ffecom_2 (NE_EXPR
, integer_type_node
,
4777 convert (TREE_TYPE (arg3_tree
),
4778 TYPE_SIZE (arg4_type
)))),
4782 = ffecom_2s (MODIFY_EXPR
, void_type_node
,
4785 /* Make sure SAVE_EXPRs get referenced early enough. */
4787 = ffecom_2 (COMPOUND_EXPR
, void_type_node
,
4789 ffecom_2 (COMPOUND_EXPR
, void_type_node
,
4791 ffecom_2 (COMPOUND_EXPR
, void_type_node
,
4793 ffecom_2 (COMPOUND_EXPR
, void_type_node
,
4797 = ffecom_2 (COMPOUND_EXPR
, void_type_node
,
4804 case FFEINTRIN_impDERF
:
4805 case FFEINTRIN_impERF
:
4806 case FFEINTRIN_impDERFC
:
4807 case FFEINTRIN_impERFC
:
4810 case FFEINTRIN_impIARGC
:
4811 /* extern int xargc; i__1 = xargc - 1; */
4812 expr_tree
= ffecom_2 (MINUS_EXPR
, TREE_TYPE (ffecom_tree_xargc_
),
4814 convert (TREE_TYPE (ffecom_tree_xargc_
),
4818 case FFEINTRIN_impSIGNAL_func
:
4819 case FFEINTRIN_impSIGNAL_subr
:
4825 arg1_tree
= convert (ffecom_f2c_integer_type_node
,
4826 ffecom_expr (arg1
));
4827 arg1_tree
= ffecom_1 (ADDR_EXPR
,
4828 build_pointer_type (TREE_TYPE (arg1_tree
)),
4831 /* Pass procedure as a pointer to it, anything else by value. */
4832 if (ffeinfo_kind (ffebld_info (arg2
)) == FFEINFO_kindENTITY
)
4833 arg2_tree
= convert (integer_type_node
, ffecom_expr (arg2
));
4835 arg2_tree
= ffecom_ptr_to_expr (arg2
);
4836 arg2_tree
= convert (TREE_TYPE (null_pointer_node
),
4840 arg3_tree
= ffecom_expr_w (NULL_TREE
, arg3
);
4842 arg3_tree
= NULL_TREE
;
4844 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
4845 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
4846 TREE_CHAIN (arg1_tree
) = arg2_tree
;
4849 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
4850 ffecom_gfrt_kindtype (gfrt
),
4852 ((codegen_imp
== FFEINTRIN_impSIGNAL_subr
) ?
4856 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
4857 ffebld_nonter_hook (expr
));
4859 if (arg3_tree
!= NULL_TREE
)
4861 = ffecom_modify (NULL_TREE
, arg3_tree
,
4862 convert (TREE_TYPE (arg3_tree
),
4867 case FFEINTRIN_impALARM
:
4873 arg1_tree
= convert (ffecom_f2c_integer_type_node
,
4874 ffecom_expr (arg1
));
4875 arg1_tree
= ffecom_1 (ADDR_EXPR
,
4876 build_pointer_type (TREE_TYPE (arg1_tree
)),
4879 /* Pass procedure as a pointer to it, anything else by value. */
4880 if (ffeinfo_kind (ffebld_info (arg2
)) == FFEINFO_kindENTITY
)
4881 arg2_tree
= convert (integer_type_node
, ffecom_expr (arg2
));
4883 arg2_tree
= ffecom_ptr_to_expr (arg2
);
4884 arg2_tree
= convert (TREE_TYPE (null_pointer_node
),
4888 arg3_tree
= ffecom_expr_w (NULL_TREE
, arg3
);
4890 arg3_tree
= NULL_TREE
;
4892 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
4893 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
4894 TREE_CHAIN (arg1_tree
) = arg2_tree
;
4897 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
4898 ffecom_gfrt_kindtype (gfrt
),
4902 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
4903 ffebld_nonter_hook (expr
));
4905 if (arg3_tree
!= NULL_TREE
)
4907 = ffecom_modify (NULL_TREE
, arg3_tree
,
4908 convert (TREE_TYPE (arg3_tree
),
4913 case FFEINTRIN_impCHDIR_subr
:
4914 case FFEINTRIN_impFDATE_subr
:
4915 case FFEINTRIN_impFGET_subr
:
4916 case FFEINTRIN_impFPUT_subr
:
4917 case FFEINTRIN_impGETCWD_subr
:
4918 case FFEINTRIN_impHOSTNM_subr
:
4919 case FFEINTRIN_impSYSTEM_subr
:
4920 case FFEINTRIN_impUNLINK_subr
:
4922 tree arg1_len
= integer_zero_node
;
4926 arg1_tree
= ffecom_arg_ptr_to_expr (arg1
, &arg1_len
);
4929 arg2_tree
= ffecom_expr_w (NULL_TREE
, arg2
);
4931 arg2_tree
= NULL_TREE
;
4933 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
4934 arg1_len
= build_tree_list (NULL_TREE
, arg1_len
);
4935 TREE_CHAIN (arg1_tree
) = arg1_len
;
4938 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
4939 ffecom_gfrt_kindtype (gfrt
),
4943 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
4944 ffebld_nonter_hook (expr
));
4946 if (arg2_tree
!= NULL_TREE
)
4948 = ffecom_modify (NULL_TREE
, arg2_tree
,
4949 convert (TREE_TYPE (arg2_tree
),
4954 case FFEINTRIN_impEXIT
:
4958 expr_tree
= build_tree_list (NULL_TREE
,
4959 ffecom_1 (ADDR_EXPR
,
4961 (ffecom_integer_type_node
),
4962 integer_zero_node
));
4965 ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
4966 ffecom_gfrt_kindtype (gfrt
),
4970 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
4971 ffebld_nonter_hook (expr
));
4973 case FFEINTRIN_impFLUSH
:
4975 gfrt
= FFECOM_gfrtFLUSH
;
4977 gfrt
= FFECOM_gfrtFLUSH1
;
4980 case FFEINTRIN_impCHMOD_subr
:
4981 case FFEINTRIN_impLINK_subr
:
4982 case FFEINTRIN_impRENAME_subr
:
4983 case FFEINTRIN_impSYMLNK_subr
:
4985 tree arg1_len
= integer_zero_node
;
4987 tree arg2_len
= integer_zero_node
;
4991 arg1_tree
= ffecom_arg_ptr_to_expr (arg1
, &arg1_len
);
4992 arg2_tree
= ffecom_arg_ptr_to_expr (arg2
, &arg2_len
);
4994 arg3_tree
= ffecom_expr_w (NULL_TREE
, arg3
);
4996 arg3_tree
= NULL_TREE
;
4998 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
4999 arg1_len
= build_tree_list (NULL_TREE
, arg1_len
);
5000 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
5001 arg2_len
= build_tree_list (NULL_TREE
, arg2_len
);
5002 TREE_CHAIN (arg1_tree
) = arg2_tree
;
5003 TREE_CHAIN (arg2_tree
) = arg1_len
;
5004 TREE_CHAIN (arg1_len
) = arg2_len
;
5005 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5006 ffecom_gfrt_kindtype (gfrt
),
5010 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
5011 ffebld_nonter_hook (expr
));
5012 if (arg3_tree
!= NULL_TREE
)
5013 expr_tree
= ffecom_modify (NULL_TREE
, arg3_tree
,
5014 convert (TREE_TYPE (arg3_tree
),
5019 case FFEINTRIN_impLSTAT_subr
:
5020 case FFEINTRIN_impSTAT_subr
:
5022 tree arg1_len
= integer_zero_node
;
5027 arg1_tree
= ffecom_arg_ptr_to_expr (arg1
, &arg1_len
);
5029 arg2_tree
= ffecom_ptr_to_expr (arg2
);
5032 arg3_tree
= ffecom_expr_w (NULL_TREE
, arg3
);
5034 arg3_tree
= NULL_TREE
;
5036 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
5037 arg1_len
= build_tree_list (NULL_TREE
, arg1_len
);
5038 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
5039 TREE_CHAIN (arg1_tree
) = arg2_tree
;
5040 TREE_CHAIN (arg2_tree
) = arg1_len
;
5041 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5042 ffecom_gfrt_kindtype (gfrt
),
5046 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
5047 ffebld_nonter_hook (expr
));
5048 if (arg3_tree
!= NULL_TREE
)
5049 expr_tree
= ffecom_modify (NULL_TREE
, arg3_tree
,
5050 convert (TREE_TYPE (arg3_tree
),
5055 case FFEINTRIN_impFGETC_subr
:
5056 case FFEINTRIN_impFPUTC_subr
:
5060 tree arg2_len
= integer_zero_node
;
5063 arg1_tree
= convert (ffecom_f2c_integer_type_node
,
5064 ffecom_expr (arg1
));
5065 arg1_tree
= ffecom_1 (ADDR_EXPR
,
5066 build_pointer_type (TREE_TYPE (arg1_tree
)),
5069 arg2_tree
= ffecom_arg_ptr_to_expr (arg2
, &arg2_len
);
5071 arg3_tree
= ffecom_expr_w (NULL_TREE
, arg3
);
5073 arg3_tree
= NULL_TREE
;
5075 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
5076 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
5077 arg2_len
= build_tree_list (NULL_TREE
, arg2_len
);
5078 TREE_CHAIN (arg1_tree
) = arg2_tree
;
5079 TREE_CHAIN (arg2_tree
) = arg2_len
;
5081 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5082 ffecom_gfrt_kindtype (gfrt
),
5086 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
5087 ffebld_nonter_hook (expr
));
5088 if (arg3_tree
!= NULL_TREE
)
5089 expr_tree
= ffecom_modify (NULL_TREE
, arg3_tree
,
5090 convert (TREE_TYPE (arg3_tree
),
5095 case FFEINTRIN_impFSTAT_subr
:
5101 arg1_tree
= convert (ffecom_f2c_integer_type_node
,
5102 ffecom_expr (arg1
));
5103 arg1_tree
= ffecom_1 (ADDR_EXPR
,
5104 build_pointer_type (TREE_TYPE (arg1_tree
)),
5107 arg2_tree
= convert (ffecom_f2c_ptr_to_integer_type_node
,
5108 ffecom_ptr_to_expr (arg2
));
5111 arg3_tree
= NULL_TREE
;
5113 arg3_tree
= ffecom_expr_w (NULL_TREE
, arg3
);
5115 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
5116 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
5117 TREE_CHAIN (arg1_tree
) = arg2_tree
;
5118 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5119 ffecom_gfrt_kindtype (gfrt
),
5123 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
5124 ffebld_nonter_hook (expr
));
5125 if (arg3_tree
!= NULL_TREE
) {
5126 expr_tree
= ffecom_modify (NULL_TREE
, arg3_tree
,
5127 convert (TREE_TYPE (arg3_tree
),
5133 case FFEINTRIN_impKILL_subr
:
5139 arg1_tree
= convert (ffecom_f2c_integer_type_node
,
5140 ffecom_expr (arg1
));
5141 arg1_tree
= ffecom_1 (ADDR_EXPR
,
5142 build_pointer_type (TREE_TYPE (arg1_tree
)),
5145 arg2_tree
= convert (ffecom_f2c_integer_type_node
,
5146 ffecom_expr (arg2
));
5147 arg2_tree
= ffecom_1 (ADDR_EXPR
,
5148 build_pointer_type (TREE_TYPE (arg2_tree
)),
5152 arg3_tree
= NULL_TREE
;
5154 arg3_tree
= ffecom_expr_w (NULL_TREE
, arg3
);
5156 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
5157 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
5158 TREE_CHAIN (arg1_tree
) = arg2_tree
;
5159 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5160 ffecom_gfrt_kindtype (gfrt
),
5164 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
5165 ffebld_nonter_hook (expr
));
5166 if (arg3_tree
!= NULL_TREE
) {
5167 expr_tree
= ffecom_modify (NULL_TREE
, arg3_tree
,
5168 convert (TREE_TYPE (arg3_tree
),
5174 case FFEINTRIN_impCTIME_subr
:
5175 case FFEINTRIN_impTTYNAM_subr
:
5177 tree arg1_len
= integer_zero_node
;
5181 arg1_tree
= ffecom_arg_ptr_to_expr (arg2
, &arg1_len
);
5183 arg2_tree
= convert (((codegen_imp
== FFEINTRIN_impCTIME_subr
) ?
5184 ffecom_f2c_longint_type_node
:
5185 ffecom_f2c_integer_type_node
),
5186 ffecom_expr (arg1
));
5187 arg2_tree
= ffecom_1 (ADDR_EXPR
,
5188 build_pointer_type (TREE_TYPE (arg2_tree
)),
5191 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
5192 arg1_len
= build_tree_list (NULL_TREE
, arg1_len
);
5193 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
5194 TREE_CHAIN (arg1_len
) = arg2_tree
;
5195 TREE_CHAIN (arg1_tree
) = arg1_len
;
5198 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5199 ffecom_gfrt_kindtype (gfrt
),
5203 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
5204 ffebld_nonter_hook (expr
));
5205 TREE_SIDE_EFFECTS (expr_tree
) = 1;
5209 case FFEINTRIN_impIRAND
:
5210 case FFEINTRIN_impRAND
:
5211 /* Arg defaults to 0 (normal random case) */
5216 arg1_tree
= ffecom_integer_zero_node
;
5218 arg1_tree
= ffecom_expr (arg1
);
5219 arg1_tree
= convert (ffecom_f2c_integer_type_node
,
5221 arg1_tree
= ffecom_1 (ADDR_EXPR
,
5222 build_pointer_type (TREE_TYPE (arg1_tree
)),
5224 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
5226 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5227 ffecom_gfrt_kindtype (gfrt
),
5229 ((codegen_imp
== FFEINTRIN_impIRAND
) ?
5230 ffecom_f2c_integer_type_node
:
5231 ffecom_f2c_real_type_node
),
5233 dest_tree
, dest
, dest_used
,
5235 ffebld_nonter_hook (expr
));
5239 case FFEINTRIN_impFTELL_subr
:
5240 case FFEINTRIN_impUMASK_subr
:
5245 arg1_tree
= convert (ffecom_f2c_integer_type_node
,
5246 ffecom_expr (arg1
));
5247 arg1_tree
= ffecom_1 (ADDR_EXPR
,
5248 build_pointer_type (TREE_TYPE (arg1_tree
)),
5252 arg2_tree
= NULL_TREE
;
5254 arg2_tree
= ffecom_expr_w (NULL_TREE
, arg2
);
5256 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5257 ffecom_gfrt_kindtype (gfrt
),
5260 build_tree_list (NULL_TREE
, arg1_tree
),
5261 NULL_TREE
, NULL
, NULL
, NULL_TREE
,
5263 ffebld_nonter_hook (expr
));
5264 if (arg2_tree
!= NULL_TREE
) {
5265 expr_tree
= ffecom_modify (NULL_TREE
, arg2_tree
,
5266 convert (TREE_TYPE (arg2_tree
),
5272 case FFEINTRIN_impCPU_TIME
:
5273 case FFEINTRIN_impSECOND_subr
:
5277 arg1_tree
= ffecom_expr_w (NULL_TREE
, arg1
);
5280 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5281 ffecom_gfrt_kindtype (gfrt
),
5285 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
5286 ffebld_nonter_hook (expr
));
5289 = ffecom_modify (NULL_TREE
, arg1_tree
,
5290 convert (TREE_TYPE (arg1_tree
),
5295 case FFEINTRIN_impDTIME_subr
:
5296 case FFEINTRIN_impETIME_subr
:
5301 result_tree
= ffecom_expr_w (NULL_TREE
, arg2
);
5303 arg1_tree
= ffecom_ptr_to_expr (arg1
);
5305 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5306 ffecom_gfrt_kindtype (gfrt
),
5309 build_tree_list (NULL_TREE
, arg1_tree
),
5310 NULL_TREE
, NULL
, NULL
, NULL_TREE
,
5312 ffebld_nonter_hook (expr
));
5313 expr_tree
= ffecom_modify (NULL_TREE
, result_tree
,
5314 convert (TREE_TYPE (result_tree
),
5319 /* Straightforward calls of libf2c routines: */
5320 case FFEINTRIN_impABORT
:
5321 case FFEINTRIN_impACCESS
:
5322 case FFEINTRIN_impBESJ0
:
5323 case FFEINTRIN_impBESJ1
:
5324 case FFEINTRIN_impBESJN
:
5325 case FFEINTRIN_impBESY0
:
5326 case FFEINTRIN_impBESY1
:
5327 case FFEINTRIN_impBESYN
:
5328 case FFEINTRIN_impCHDIR_func
:
5329 case FFEINTRIN_impCHMOD_func
:
5330 case FFEINTRIN_impDATE
:
5331 case FFEINTRIN_impDATE_AND_TIME
:
5332 case FFEINTRIN_impDBESJ0
:
5333 case FFEINTRIN_impDBESJ1
:
5334 case FFEINTRIN_impDBESJN
:
5335 case FFEINTRIN_impDBESY0
:
5336 case FFEINTRIN_impDBESY1
:
5337 case FFEINTRIN_impDBESYN
:
5338 case FFEINTRIN_impDTIME_func
:
5339 case FFEINTRIN_impETIME_func
:
5340 case FFEINTRIN_impFGETC_func
:
5341 case FFEINTRIN_impFGET_func
:
5342 case FFEINTRIN_impFNUM
:
5343 case FFEINTRIN_impFPUTC_func
:
5344 case FFEINTRIN_impFPUT_func
:
5345 case FFEINTRIN_impFSEEK
:
5346 case FFEINTRIN_impFSTAT_func
:
5347 case FFEINTRIN_impFTELL_func
:
5348 case FFEINTRIN_impGERROR
:
5349 case FFEINTRIN_impGETARG
:
5350 case FFEINTRIN_impGETCWD_func
:
5351 case FFEINTRIN_impGETENV
:
5352 case FFEINTRIN_impGETGID
:
5353 case FFEINTRIN_impGETLOG
:
5354 case FFEINTRIN_impGETPID
:
5355 case FFEINTRIN_impGETUID
:
5356 case FFEINTRIN_impGMTIME
:
5357 case FFEINTRIN_impHOSTNM_func
:
5358 case FFEINTRIN_impIDATE_unix
:
5359 case FFEINTRIN_impIDATE_vxt
:
5360 case FFEINTRIN_impIERRNO
:
5361 case FFEINTRIN_impISATTY
:
5362 case FFEINTRIN_impITIME
:
5363 case FFEINTRIN_impKILL_func
:
5364 case FFEINTRIN_impLINK_func
:
5365 case FFEINTRIN_impLNBLNK
:
5366 case FFEINTRIN_impLSTAT_func
:
5367 case FFEINTRIN_impLTIME
:
5368 case FFEINTRIN_impMCLOCK8
:
5369 case FFEINTRIN_impMCLOCK
:
5370 case FFEINTRIN_impPERROR
:
5371 case FFEINTRIN_impRENAME_func
:
5372 case FFEINTRIN_impSECNDS
:
5373 case FFEINTRIN_impSECOND_func
:
5374 case FFEINTRIN_impSLEEP
:
5375 case FFEINTRIN_impSRAND
:
5376 case FFEINTRIN_impSTAT_func
:
5377 case FFEINTRIN_impSYMLNK_func
:
5378 case FFEINTRIN_impSYSTEM_CLOCK
:
5379 case FFEINTRIN_impSYSTEM_func
:
5380 case FFEINTRIN_impTIME8
:
5381 case FFEINTRIN_impTIME_unix
:
5382 case FFEINTRIN_impTIME_vxt
:
5383 case FFEINTRIN_impUMASK_func
:
5384 case FFEINTRIN_impUNLINK_func
:
5387 case FFEINTRIN_impCTIME_func
: /* CHARACTER functions not handled here. */
5388 case FFEINTRIN_impFDATE_func
: /* CHARACTER functions not handled here. */
5389 case FFEINTRIN_impTTYNAM_func
: /* CHARACTER functions not handled here. */
5390 case FFEINTRIN_impNONE
:
5391 case FFEINTRIN_imp
: /* Hush up gcc warning. */
5392 fprintf (stderr
, "No %s implementation.\n",
5393 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr
))));
5394 assert ("unimplemented intrinsic" == NULL
);
5395 return error_mark_node
;
5398 assert (gfrt
!= FFECOM_gfrt
); /* Must have an implementation! */
5400 expr_tree
= ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt
),
5401 ffebld_right (expr
));
5403 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt
), ffecom_gfrt_kindtype (gfrt
),
5404 (ffe_is_f2c_library () && ffecom_gfrt_complex_
[gfrt
]),
5406 expr_tree
, dest_tree
, dest
, dest_used
,
5408 ffebld_nonter_hook (expr
));
5410 /* See bottom of this file for f2c transforms used to determine
5411 many of the above implementations. The info seems to confuse
5412 Emacs's C mode indentation, which is why it's been moved to
5413 the bottom of this source file. */
5416 /* For power (exponentiation) where right-hand operand is type INTEGER,
5417 generate in-line code to do it the fast way (which, if the operand
5418 is a constant, might just mean a series of multiplies). */
5421 ffecom_expr_power_integer_ (ffebld expr
)
5423 tree l
= ffecom_expr (ffebld_left (expr
));
5424 tree r
= ffecom_expr (ffebld_right (expr
));
5425 tree ltype
= TREE_TYPE (l
);
5426 tree rtype
= TREE_TYPE (r
);
5427 tree result
= NULL_TREE
;
5429 if (l
== error_mark_node
5430 || r
== error_mark_node
)
5431 return error_mark_node
;
5433 if (TREE_CODE (r
) == INTEGER_CST
)
5435 int sgn
= tree_int_cst_sgn (r
);
5438 return convert (ltype
, integer_one_node
);
5440 if ((TREE_CODE (ltype
) == INTEGER_TYPE
)
5443 /* Reciprocal of integer is either 0, -1, or 1, so after
5444 calculating that (which we leave to the back end to do
5445 or not do optimally), don't bother with any multiplying. */
5447 result
= ffecom_tree_divide_ (ltype
,
5448 convert (ltype
, integer_one_node
),
5450 NULL_TREE
, NULL
, NULL
, NULL_TREE
);
5451 r
= ffecom_1 (NEGATE_EXPR
,
5454 if ((TREE_INT_CST_LOW (r
) & 1) == 0)
5455 result
= ffecom_1 (ABS_EXPR
, rtype
,
5459 /* Generate appropriate series of multiplies, preceded
5460 by divide if the exponent is negative. */
5466 l
= ffecom_tree_divide_ (ltype
,
5467 convert (ltype
, integer_one_node
),
5469 NULL_TREE
, NULL
, NULL
,
5470 ffebld_nonter_hook (expr
));
5471 r
= ffecom_1 (NEGATE_EXPR
, rtype
, r
);
5472 assert (TREE_CODE (r
) == INTEGER_CST
);
5474 if (tree_int_cst_sgn (r
) < 0)
5475 { /* The "most negative" number. */
5476 r
= ffecom_1 (NEGATE_EXPR
, rtype
,
5477 ffecom_2 (RSHIFT_EXPR
, rtype
,
5481 l
= ffecom_2 (MULT_EXPR
, ltype
,
5489 if (TREE_INT_CST_LOW (r
) & 1)
5491 if (result
== NULL_TREE
)
5494 result
= ffecom_2 (MULT_EXPR
, ltype
,
5499 r
= ffecom_2 (RSHIFT_EXPR
, rtype
,
5502 if (integer_zerop (r
))
5504 assert (TREE_CODE (r
) == INTEGER_CST
);
5507 l
= ffecom_2 (MULT_EXPR
, ltype
,
5514 /* Though rhs isn't a constant, in-line code cannot be expanded
5515 while transforming dummies
5516 because the back end cannot be easily convinced to generate
5517 stores (MODIFY_EXPR), handle temporaries, and so on before
5518 all the appropriate rtx's have been generated for things like
5519 dummy args referenced in rhs -- which doesn't happen until
5520 store_parm_decls() is called (expand_function_start, I believe,
5521 does the actual rtx-stuffing of PARM_DECLs).
5523 So, in this case, let the caller generate the call to the
5524 run-time-library function to evaluate the power for us. */
5526 if (ffecom_transform_only_dummies_
)
5529 /* Right-hand operand not a constant, expand in-line code to figure
5530 out how to do the multiplies, &c.
5532 The returned expression is expressed this way in GNU C, where l and
5535 ({ typeof (r) rtmp = r;
5536 typeof (l) ltmp = l;
5543 if ((basetypeof (l) == basetypeof (int))
5546 result = ((typeof (l)) 1) / ltmp;
5547 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5553 if ((basetypeof (l) != basetypeof (int))
5556 ltmp = ((typeof (l)) 1) / ltmp;
5560 rtmp = -(rtmp >> 1);
5568 if ((rtmp >>= 1) == 0)
5577 Note that some of the above is compile-time collapsable, such as
5578 the first part of the if statements that checks the base type of
5579 l against int. The if statements are phrased that way to suggest
5580 an easy way to generate the if/else constructs here, knowing that
5581 the back end should (and probably does) eliminate the resulting
5582 dead code (either the int case or the non-int case), something
5583 it couldn't do without the redundant phrasing, requiring explicit
5584 dead-code elimination here, which would be kind of difficult to
5591 tree basetypeof_l_is_int
;
5596 = build_int_2 ((TREE_CODE (ltype
) == INTEGER_TYPE
), 0);
5598 se
= expand_start_stmt_expr (/*has_scope=*/1);
5600 ffecom_start_compstmt ();
5602 rtmp
= ffecom_make_tempvar ("power_r", rtype
,
5603 FFETARGET_charactersizeNONE
, -1);
5604 ltmp
= ffecom_make_tempvar ("power_l", ltype
,
5605 FFETARGET_charactersizeNONE
, -1);
5606 result
= ffecom_make_tempvar ("power_res", ltype
,
5607 FFETARGET_charactersizeNONE
, -1);
5608 if (TREE_CODE (ltype
) == COMPLEX_TYPE
5609 || TREE_CODE (ltype
) == RECORD_TYPE
)
5610 divide
= ffecom_make_tempvar ("power_div", ltype
,
5611 FFETARGET_charactersizeNONE
, -1);
5615 expand_expr_stmt (ffecom_modify (void_type_node
,
5618 expand_expr_stmt (ffecom_modify (void_type_node
,
5621 expand_start_cond (ffecom_truth_value
5622 (ffecom_2 (EQ_EXPR
, integer_type_node
,
5624 convert (rtype
, integer_zero_node
))),
5626 expand_expr_stmt (ffecom_modify (void_type_node
,
5628 convert (ltype
, integer_one_node
)));
5629 expand_start_else ();
5630 if (! integer_zerop (basetypeof_l_is_int
))
5632 expand_start_cond (ffecom_2 (LT_EXPR
, integer_type_node
,
5635 integer_zero_node
)),
5637 expand_expr_stmt (ffecom_modify (void_type_node
,
5641 convert (ltype
, integer_one_node
),
5643 NULL_TREE
, NULL
, NULL
,
5645 expand_start_cond (ffecom_truth_value
5646 (ffecom_2 (TRUTH_ANDIF_EXPR
, integer_type_node
,
5647 ffecom_2 (LT_EXPR
, integer_type_node
,
5650 integer_zero_node
)),
5651 ffecom_2 (EQ_EXPR
, integer_type_node
,
5652 ffecom_2 (BIT_AND_EXPR
,
5654 ffecom_1 (NEGATE_EXPR
,
5660 integer_zero_node
)))),
5662 expand_expr_stmt (ffecom_modify (void_type_node
,
5664 ffecom_1 (NEGATE_EXPR
,
5668 expand_start_else ();
5670 expand_expr_stmt (ffecom_modify (void_type_node
,
5672 convert (ltype
, integer_one_node
)));
5673 expand_start_cond (ffecom_truth_value
5674 (ffecom_2 (TRUTH_ANDIF_EXPR
, integer_type_node
,
5675 ffecom_truth_value_invert
5676 (basetypeof_l_is_int
),
5677 ffecom_2 (LT_EXPR
, integer_type_node
,
5680 integer_zero_node
)))),
5682 expand_expr_stmt (ffecom_modify (void_type_node
,
5686 convert (ltype
, integer_one_node
),
5688 NULL_TREE
, NULL
, NULL
,
5690 expand_expr_stmt (ffecom_modify (void_type_node
,
5692 ffecom_1 (NEGATE_EXPR
, rtype
,
5694 expand_start_cond (ffecom_truth_value
5695 (ffecom_2 (LT_EXPR
, integer_type_node
,
5697 convert (rtype
, integer_zero_node
))),
5699 expand_expr_stmt (ffecom_modify (void_type_node
,
5701 ffecom_1 (NEGATE_EXPR
, rtype
,
5702 ffecom_2 (RSHIFT_EXPR
,
5705 integer_one_node
))));
5706 expand_expr_stmt (ffecom_modify (void_type_node
,
5708 ffecom_2 (MULT_EXPR
, ltype
,
5713 expand_start_loop (1);
5714 expand_start_cond (ffecom_truth_value
5715 (ffecom_2 (BIT_AND_EXPR
, rtype
,
5717 convert (rtype
, integer_one_node
))),
5719 expand_expr_stmt (ffecom_modify (void_type_node
,
5721 ffecom_2 (MULT_EXPR
, ltype
,
5725 expand_exit_loop_if_false (NULL
,
5727 (ffecom_modify (rtype
,
5729 ffecom_2 (RSHIFT_EXPR
,
5732 integer_one_node
))));
5733 expand_expr_stmt (ffecom_modify (void_type_node
,
5735 ffecom_2 (MULT_EXPR
, ltype
,
5740 if (!integer_zerop (basetypeof_l_is_int
))
5742 expand_expr_stmt (result
);
5744 t
= ffecom_end_compstmt ();
5746 result
= expand_end_stmt_expr (se
);
5748 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5750 if (TREE_CODE (t
) == BLOCK
)
5752 /* Make a BIND_EXPR for the BLOCK already made. */
5753 result
= build (BIND_EXPR
, TREE_TYPE (result
),
5754 NULL_TREE
, result
, t
);
5755 /* Remove the block from the tree at this point.
5756 It gets put back at the proper place
5757 when the BIND_EXPR is expanded. */
5767 /* ffecom_expr_transform_ -- Transform symbols in expr
5769 ffebld expr; // FFE expression.
5770 ffecom_expr_transform_ (expr);
5772 Recursive descent on expr while transforming any untransformed SYMTERs. */
5775 ffecom_expr_transform_ (ffebld expr
)
5785 switch (ffebld_op (expr
))
5787 case FFEBLD_opSYMTER
:
5788 s
= ffebld_symter (expr
);
5789 t
= ffesymbol_hook (s
).decl_tree
;
5790 if ((t
== NULL_TREE
)
5791 && ((ffesymbol_kind (s
) != FFEINFO_kindNONE
)
5792 || ((ffesymbol_where (s
) != FFEINFO_whereNONE
)
5793 && (ffesymbol_where (s
) != FFEINFO_whereINTRINSIC
))))
5795 s
= ffecom_sym_transform_ (s
);
5796 t
= ffesymbol_hook (s
).decl_tree
; /* Sfunc expr non-dummy,
5799 break; /* Ok if (t == NULL) here. */
5802 ffecom_expr_transform_ (ffebld_head (expr
));
5803 expr
= ffebld_trail (expr
);
5804 goto tail_recurse
; /* :::::::::::::::::::: */
5810 switch (ffebld_arity (expr
))
5813 ffecom_expr_transform_ (ffebld_left (expr
));
5814 expr
= ffebld_right (expr
);
5815 goto tail_recurse
; /* :::::::::::::::::::: */
5818 expr
= ffebld_left (expr
);
5819 goto tail_recurse
; /* :::::::::::::::::::: */
5828 /* Make a type based on info in live f2c.h file. */
5831 ffecom_f2c_make_type_ (tree
*type
, int tcode
, const char *name
)
5835 case FFECOM_f2ccodeCHAR
:
5836 *type
= make_signed_type (CHAR_TYPE_SIZE
);
5839 case FFECOM_f2ccodeSHORT
:
5840 *type
= make_signed_type (SHORT_TYPE_SIZE
);
5843 case FFECOM_f2ccodeINT
:
5844 *type
= make_signed_type (INT_TYPE_SIZE
);
5847 case FFECOM_f2ccodeLONG
:
5848 *type
= make_signed_type (LONG_TYPE_SIZE
);
5851 case FFECOM_f2ccodeLONGLONG
:
5852 *type
= make_signed_type (LONG_LONG_TYPE_SIZE
);
5855 case FFECOM_f2ccodeCHARPTR
:
5856 *type
= build_pointer_type (DEFAULT_SIGNED_CHAR
5857 ? signed_char_type_node
5858 : unsigned_char_type_node
);
5861 case FFECOM_f2ccodeFLOAT
:
5862 *type
= make_node (REAL_TYPE
);
5863 TYPE_PRECISION (*type
) = FLOAT_TYPE_SIZE
;
5864 layout_type (*type
);
5867 case FFECOM_f2ccodeDOUBLE
:
5868 *type
= make_node (REAL_TYPE
);
5869 TYPE_PRECISION (*type
) = DOUBLE_TYPE_SIZE
;
5870 layout_type (*type
);
5873 case FFECOM_f2ccodeLONGDOUBLE
:
5874 *type
= make_node (REAL_TYPE
);
5875 TYPE_PRECISION (*type
) = LONG_DOUBLE_TYPE_SIZE
;
5876 layout_type (*type
);
5879 case FFECOM_f2ccodeTWOREALS
:
5880 *type
= ffecom_make_complex_type_ (ffecom_f2c_real_type_node
);
5883 case FFECOM_f2ccodeTWODOUBLEREALS
:
5884 *type
= ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node
);
5888 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL
);
5889 *type
= error_mark_node
;
5893 pushdecl (build_decl (TYPE_DECL
,
5894 ffecom_get_invented_identifier ("__g77_f2c_%s", name
),
5898 /* Set the f2c list-directed-I/O code for whatever (integral) type has the
5902 ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt
, int size
, int code
)
5907 for (j
= 0; ((size_t) j
) < ARRAY_SIZE (ffecom_tree_type
[0]); ++j
)
5908 if ((t
= ffecom_tree_type
[bt
][j
]) != NULL_TREE
5909 && compare_tree_int (TYPE_SIZE (t
), size
) == 0)
5911 assert (code
!= -1);
5912 ffecom_f2c_typecode_
[bt
][j
] = code
;
5917 /* Finish up globals after doing all program units in file
5919 Need to handle only uninitialized COMMON areas. */
5922 ffecom_finish_global_ (ffeglobal global
)
5928 if (ffeglobal_type (global
) != FFEGLOBAL_typeCOMMON
)
5931 if (ffeglobal_common_init (global
))
5934 cbt
= ffeglobal_hook (global
);
5935 if ((cbt
== NULL_TREE
)
5936 || !ffeglobal_common_have_size (global
))
5937 return global
; /* No need to make common, never ref'd. */
5939 DECL_EXTERNAL (cbt
) = 0;
5941 /* Give the array a size now. */
5943 size
= build_int_2 ((ffeglobal_common_size (global
)
5944 + ffeglobal_common_pad (global
)) - 1,
5947 cbtype
= TREE_TYPE (cbt
);
5948 TYPE_DOMAIN (cbtype
) = build_range_type (integer_type_node
,
5951 if (!TREE_TYPE (size
))
5952 TREE_TYPE (size
) = TYPE_DOMAIN (cbtype
);
5953 layout_type (cbtype
);
5955 cbt
= start_decl (cbt
, FALSE
);
5956 assert (cbt
== ffeglobal_hook (global
));
5958 finish_decl (cbt
, NULL_TREE
, FALSE
);
5963 /* Finish up any untransformed symbols. */
5966 ffecom_finish_symbol_transform_ (ffesymbol s
)
5968 if ((s
== NULL
) || (TREE_CODE (current_function_decl
) == ERROR_MARK
))
5971 /* It's easy to know to transform an untransformed symbol, to make sure
5972 we put out debugging info for it. But COMMON variables, unlike
5973 EQUIVALENCE ones, aren't given declarations in addition to the
5974 tree expressions that specify offsets, because COMMON variables
5975 can be referenced in the outer scope where only dummy arguments
5976 (PARM_DECLs) should really be seen. To be safe, just don't do any
5977 VAR_DECLs for COMMON variables when we transform them for real
5978 use, and therefore we do all the VAR_DECL creating here. */
5980 if (ffesymbol_hook (s
).decl_tree
== NULL_TREE
)
5982 if (ffesymbol_kind (s
) != FFEINFO_kindNONE
5983 || (ffesymbol_where (s
) != FFEINFO_whereNONE
5984 && ffesymbol_where (s
) != FFEINFO_whereINTRINSIC
5985 && ffesymbol_where (s
) != FFEINFO_whereDUMMY
))
5986 /* Not transformed, and not CHARACTER*(*), and not a dummy
5987 argument, which can happen only if the entry point names
5988 it "rides in on" are all invalidated for other reasons. */
5989 s
= ffecom_sym_transform_ (s
);
5992 if ((ffesymbol_where (s
) == FFEINFO_whereCOMMON
)
5993 && (ffesymbol_hook (s
).decl_tree
!= error_mark_node
))
5995 /* This isn't working, at least for dbxout. The .s file looks
5996 okay to me (burley), but in gdb 4.9 at least, the variables
5997 appear to reside somewhere outside of the common area, so
5998 it doesn't make sense to mislead anyone by generating the info
5999 on those variables until this is fixed. NOTE: Same problem
6000 with EQUIVALENCE, sadly...see similar #if later. */
6001 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s
)),
6002 ffesymbol_storage (s
));
6008 /* Append underscore(s) to name before calling get_identifier. "us"
6009 is nonzero if the name already contains an underscore and thus
6010 needs two underscores appended. */
6013 ffecom_get_appended_identifier_ (char us
, const char *name
)
6019 newname
= xmalloc ((i
= strlen (name
)) + 1
6020 + ffe_is_underscoring ()
6022 memcpy (newname
, name
, i
);
6024 newname
[i
+ us
] = '_';
6025 newname
[i
+ 1 + us
] = '\0';
6026 id
= get_identifier (newname
);
6033 /* Decide whether to append underscore to name before calling
6037 ffecom_get_external_identifier_ (ffesymbol s
)
6040 const char *name
= ffesymbol_text (s
);
6042 /* If name is a built-in name, just return it as is. */
6044 if (!ffe_is_underscoring ()
6045 || (strcmp (name
, FFETARGET_nameBLANK_COMMON
) == 0)
6046 || (strcmp (name
, FFETARGET_nameUNNAMED_MAIN
) == 0)
6047 || (strcmp (name
, FFETARGET_nameUNNAMED_BLOCK_DATA
) == 0))
6048 return get_identifier (name
);
6050 us
= ffe_is_second_underscore ()
6051 ? (strchr (name
, '_') != NULL
)
6054 return ffecom_get_appended_identifier_ (us
, name
);
6057 /* Decide whether to append underscore to internal name before calling
6060 This is for non-external, top-function-context names only. Transform
6061 identifier so it doesn't conflict with the transformed result
6062 of using a _different_ external name. E.g. if "CALL FOO" is
6063 transformed into "FOO_();", then the variable in "FOO_ = 3"
6064 must be transformed into something that does not conflict, since
6065 these two things should be independent.
6067 The transformation is as follows. If the name does not contain
6068 an underscore, there is no possible conflict, so just return.
6069 If the name does contain an underscore, then transform it just
6070 like we transform an external identifier. */
6073 ffecom_get_identifier_ (const char *name
)
6075 /* If name does not contain an underscore, just return it as is. */
6077 if (!ffe_is_underscoring ()
6078 || (strchr (name
, '_') == NULL
))
6079 return get_identifier (name
);
6081 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6085 /* ffecom_gen_sfuncdef_ -- Generate definition of statement function
6088 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6089 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6090 ffesymbol_kindtype(s));
6092 Call after setting up containing function and getting trees for all
6096 ffecom_gen_sfuncdef_ (ffesymbol s
, ffeinfoBasictype bt
, ffeinfoKindtype kt
)
6098 ffebld expr
= ffesymbol_sfexpr (s
);
6102 bool charfunc
= (bt
== FFEINFO_basictypeCHARACTER
);
6103 static bool recurse
= FALSE
;
6104 location_t old_loc
= input_location
;
6106 ffecom_nested_entry_
= s
;
6108 /* For now, we don't have a handy pointer to where the sfunc is actually
6109 defined, though that should be easy to add to an ffesymbol. (The
6110 token/where info available might well point to the place where the type
6111 of the sfunc is declared, especially if that precedes the place where
6112 the sfunc itself is defined, which is typically the case.) We should
6113 put out a null pointer rather than point somewhere wrong, but I want to
6114 see how it works at this point. */
6116 input_filename
= ffesymbol_where_filename (s
);
6117 input_line
= ffesymbol_where_filelinenum (s
);
6119 /* Pretransform the expression so any newly discovered things belong to the
6120 outer program unit, not to the statement function. */
6122 ffecom_expr_transform_ (expr
);
6124 /* Make sure no recursive invocation of this fn (a specific case of failing
6125 to pretransform an sfunc's expression, i.e. where its expression
6126 references another untransformed sfunc) happens. */
6131 push_f_function_context ();
6134 type
= void_type_node
;
6137 type
= ffecom_tree_type
[bt
][kt
];
6138 if (type
== NULL_TREE
)
6139 type
= integer_type_node
; /* _sym_exec_transition reports
6143 start_function (ffecom_get_identifier_ (ffesymbol_text (s
)),
6144 build_function_type (type
, NULL_TREE
),
6145 1, /* nested/inline */
6146 0); /* TREE_PUBLIC */
6148 /* We don't worry about COMPLEX return values here, because this is
6149 entirely internal to our code, and gcc has the ability to return COMPLEX
6150 directly as a value. */
6153 { /* Prepend arg for where result goes. */
6156 type
= ffecom_tree_type
[FFEINFO_basictypeCHARACTER
][kt
];
6158 result
= ffecom_get_invented_identifier ("__g77_%s", "result");
6160 ffecom_char_enhance_arg_ (&type
, s
); /* Ignore returned length. */
6162 type
= build_pointer_type (type
);
6163 result
= build_decl (PARM_DECL
, result
, type
);
6165 push_parm_decl (result
);
6168 result
= NULL_TREE
; /* Not ref'd if !charfunc. */
6170 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s
), TRUE
);
6172 store_parm_decls (0);
6174 ffecom_start_compstmt ();
6180 ffetargetCharacterSize sz
= ffesymbol_size (s
);
6183 result_length
= build_int_2 (sz
, 0);
6184 TREE_TYPE (result_length
) = ffecom_f2c_ftnlen_type_node
;
6186 ffecom_prepare_let_char_ (sz
, expr
);
6188 ffecom_prepare_end ();
6190 ffecom_let_char_ (result
, result_length
, sz
, expr
);
6191 expand_null_return ();
6195 ffecom_prepare_expr (expr
);
6197 ffecom_prepare_end ();
6199 expand_return (ffecom_modify (NULL_TREE
,
6200 DECL_RESULT (current_function_decl
),
6201 ffecom_expr (expr
)));
6205 ffecom_end_compstmt ();
6207 func
= current_function_decl
;
6208 finish_function (1);
6210 pop_f_function_context ();
6214 input_location
= old_loc
;
6216 ffecom_nested_entry_
= NULL
;
6222 ffecom_gfrt_args_ (ffecomGfrt ix
)
6224 return ffecom_gfrt_argstring_
[ix
];
6228 ffecom_gfrt_tree_ (ffecomGfrt ix
)
6230 if (ffecom_gfrt_
[ix
] == NULL_TREE
)
6231 ffecom_make_gfrt_ (ix
);
6233 return ffecom_1 (ADDR_EXPR
,
6234 build_pointer_type (TREE_TYPE (ffecom_gfrt_
[ix
])),
6238 /* Return initialize-to-zero expression for this VAR_DECL. */
6240 /* A somewhat evil way to prevent the garbage collector
6241 from collecting 'tree' structures. */
6242 #define NUM_TRACKED_CHUNK 63
6243 struct tree_ggc_tracker
GTY(())
6245 struct tree_ggc_tracker
*next
;
6246 tree trees
[NUM_TRACKED_CHUNK
];
6248 static GTY(()) struct tree_ggc_tracker
*tracker_head
;
6251 ffecom_save_tree_forever (tree t
)
6254 if (tracker_head
!= NULL
)
6255 for (i
= 0; i
< NUM_TRACKED_CHUNK
; i
++)
6256 if (tracker_head
->trees
[i
] == NULL
)
6258 tracker_head
->trees
[i
] = t
;
6263 /* Need to allocate a new block. */
6264 struct tree_ggc_tracker
*old_head
= tracker_head
;
6266 tracker_head
= ggc_alloc (sizeof (*tracker_head
));
6267 tracker_head
->next
= old_head
;
6268 tracker_head
->trees
[0] = t
;
6269 for (i
= 1; i
< NUM_TRACKED_CHUNK
; i
++)
6270 tracker_head
->trees
[i
] = NULL
;
6275 ffecom_init_zero_ (tree decl
)
6278 int incremental
= TREE_STATIC (decl
);
6279 tree type
= TREE_TYPE (decl
);
6283 make_decl_rtl (decl
, NULL
);
6284 assemble_variable (decl
, TREE_PUBLIC (decl
) ? 1 : 0, 0, 1);
6287 if ((TREE_CODE (type
) != ARRAY_TYPE
)
6288 && (TREE_CODE (type
) != RECORD_TYPE
)
6289 && (TREE_CODE (type
) != UNION_TYPE
)
6291 init
= convert (type
, integer_zero_node
);
6292 else if (!incremental
)
6294 init
= build_constructor (type
, NULL_TREE
);
6295 TREE_CONSTANT (init
) = 1;
6296 TREE_STATIC (init
) = 1;
6300 assemble_zeros (int_size_in_bytes (type
));
6301 init
= error_mark_node
;
6308 ffecom_intrinsic_ichar_ (tree tree_type
, ffebld arg
, tree
*maybe_tree
)
6313 switch (ffebld_op (arg
))
6315 case FFEBLD_opCONTER
: /* For F90, check 0-length. */
6316 if (ffetarget_length_character1
6317 (ffebld_constant_character1
6318 (ffebld_conter (arg
))) == 0)
6320 *maybe_tree
= integer_zero_node
;
6321 return convert (tree_type
, integer_zero_node
);
6324 *maybe_tree
= integer_one_node
;
6325 expr_tree
= build_int_2 (*ffetarget_text_character1
6326 (ffebld_constant_character1
6327 (ffebld_conter (arg
))),
6329 TREE_TYPE (expr_tree
) = tree_type
;
6332 case FFEBLD_opSYMTER
:
6333 case FFEBLD_opARRAYREF
:
6334 case FFEBLD_opFUNCREF
:
6335 case FFEBLD_opSUBSTR
:
6336 ffecom_char_args_ (&expr_tree
, &length_tree
, arg
);
6338 if ((expr_tree
== error_mark_node
)
6339 || (length_tree
== error_mark_node
))
6341 *maybe_tree
= error_mark_node
;
6342 return error_mark_node
;
6345 if (integer_zerop (length_tree
))
6347 *maybe_tree
= integer_zero_node
;
6348 return convert (tree_type
, integer_zero_node
);
6352 = ffecom_1 (INDIRECT_REF
,
6353 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree
))),
6356 = ffecom_2 (ARRAY_REF
,
6357 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree
))),
6360 expr_tree
= convert (tree_type
, expr_tree
);
6362 if (TREE_CODE (length_tree
) == INTEGER_CST
)
6363 *maybe_tree
= integer_one_node
;
6364 else /* Must check length at run time. */
6366 = ffecom_truth_value
6367 (ffecom_2 (GT_EXPR
, integer_type_node
,
6369 ffecom_f2c_ftnlen_zero_node
));
6372 case FFEBLD_opPAREN
:
6373 case FFEBLD_opCONVERT
:
6374 if (ffeinfo_size (ffebld_info (arg
)) == 0)
6376 *maybe_tree
= integer_zero_node
;
6377 return convert (tree_type
, integer_zero_node
);
6379 return ffecom_intrinsic_ichar_ (tree_type
, ffebld_left (arg
),
6382 case FFEBLD_opCONCATENATE
:
6389 expr_left
= ffecom_intrinsic_ichar_ (tree_type
, ffebld_left (arg
),
6391 expr_right
= ffecom_intrinsic_ichar_ (tree_type
, ffebld_right (arg
),
6393 *maybe_tree
= ffecom_2 (TRUTH_ORIF_EXPR
, integer_type_node
,
6396 expr_tree
= ffecom_3 (COND_EXPR
, tree_type
,
6404 assert ("bad op in ICHAR" == NULL
);
6405 return error_mark_node
;
6409 /* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6413 length_arg = ffecom_intrinsic_len_ (expr);
6415 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6416 subexpressions by constructing the appropriate tree for the
6417 length-of-character-text argument in a calling sequence. */
6420 ffecom_intrinsic_len_ (ffebld expr
)
6422 ffetargetCharacter1 val
;
6425 switch (ffebld_op (expr
))
6427 case FFEBLD_opCONTER
:
6428 val
= ffebld_constant_character1 (ffebld_conter (expr
));
6429 length
= build_int_2 (ffetarget_length_character1 (val
), 0);
6430 TREE_TYPE (length
) = ffecom_f2c_ftnlen_type_node
;
6433 case FFEBLD_opSYMTER
:
6435 ffesymbol s
= ffebld_symter (expr
);
6438 item
= ffesymbol_hook (s
).decl_tree
;
6439 if (item
== NULL_TREE
)
6441 s
= ffecom_sym_transform_ (s
);
6442 item
= ffesymbol_hook (s
).decl_tree
;
6444 if (ffesymbol_kind (s
) == FFEINFO_kindENTITY
)
6446 if (ffesymbol_size (s
) == FFETARGET_charactersizeNONE
)
6447 length
= ffesymbol_hook (s
).length_tree
;
6450 length
= build_int_2 (ffesymbol_size (s
), 0);
6451 TREE_TYPE (length
) = ffecom_f2c_ftnlen_type_node
;
6454 else if (item
== error_mark_node
)
6455 length
= error_mark_node
;
6456 else /* FFEINFO_kindFUNCTION: */
6461 case FFEBLD_opARRAYREF
:
6462 length
= ffecom_intrinsic_len_ (ffebld_left (expr
));
6465 case FFEBLD_opSUBSTR
:
6469 ffebld thing
= ffebld_right (expr
);
6473 assert (ffebld_op (thing
) == FFEBLD_opITEM
);
6474 start
= ffebld_head (thing
);
6475 thing
= ffebld_trail (thing
);
6476 assert (ffebld_trail (thing
) == NULL
);
6477 end
= ffebld_head (thing
);
6479 length
= ffecom_intrinsic_len_ (ffebld_left (expr
));
6481 if (length
== error_mark_node
)
6490 length
= convert (ffecom_f2c_ftnlen_type_node
,
6496 start_tree
= convert (ffecom_f2c_ftnlen_type_node
,
6497 ffecom_expr (start
));
6499 if (start_tree
== error_mark_node
)
6501 length
= error_mark_node
;
6507 length
= ffecom_2 (PLUS_EXPR
, ffecom_f2c_ftnlen_type_node
,
6508 ffecom_f2c_ftnlen_one_node
,
6509 ffecom_2 (MINUS_EXPR
,
6510 ffecom_f2c_ftnlen_type_node
,
6516 end_tree
= convert (ffecom_f2c_ftnlen_type_node
,
6519 if (end_tree
== error_mark_node
)
6521 length
= error_mark_node
;
6525 length
= ffecom_2 (PLUS_EXPR
, ffecom_f2c_ftnlen_type_node
,
6526 ffecom_f2c_ftnlen_one_node
,
6527 ffecom_2 (MINUS_EXPR
,
6528 ffecom_f2c_ftnlen_type_node
,
6529 end_tree
, start_tree
));
6535 case FFEBLD_opCONCATENATE
:
6537 = ffecom_2 (PLUS_EXPR
, ffecom_f2c_ftnlen_type_node
,
6538 ffecom_intrinsic_len_ (ffebld_left (expr
)),
6539 ffecom_intrinsic_len_ (ffebld_right (expr
)));
6542 case FFEBLD_opFUNCREF
:
6543 case FFEBLD_opCONVERT
:
6544 length
= build_int_2 (ffebld_size (expr
), 0);
6545 TREE_TYPE (length
) = ffecom_f2c_ftnlen_type_node
;
6549 assert ("bad op for single char arg expr" == NULL
);
6550 length
= ffecom_f2c_ftnlen_zero_node
;
6554 assert (length
!= NULL_TREE
);
6559 /* Handle CHARACTER assignments.
6561 Generates code to do the assignment. Used by ordinary assignment
6562 statement handler ffecom_let_stmt and by statement-function
6563 handler to generate code for a statement function. */
6566 ffecom_let_char_ (tree dest_tree
, tree dest_length
,
6567 ffetargetCharacterSize dest_size
, ffebld source
)
6569 ffecomConcatList_ catlist
;
6574 if ((dest_tree
== error_mark_node
)
6575 || (dest_length
== error_mark_node
))
6578 assert (dest_tree
!= NULL_TREE
);
6579 assert (dest_length
!= NULL_TREE
);
6581 /* Source might be an opCONVERT, which just means it is a different size
6582 than the destination. Since the underlying implementation here handles
6583 that (directly or via the s_copy or s_cat run-time-library functions),
6584 we don't need the "convenience" of an opCONVERT that tells us to
6585 truncate or blank-pad, particularly since the resulting implementation
6586 would probably be slower than otherwise. */
6588 while (ffebld_op (source
) == FFEBLD_opCONVERT
)
6589 source
= ffebld_left (source
);
6591 catlist
= ffecom_concat_list_new_ (source
, dest_size
);
6592 switch (ffecom_concat_list_count_ (catlist
))
6594 case 0: /* Shouldn't happen, but in case it does... */
6595 ffecom_concat_list_kill_ (catlist
);
6596 source_tree
= null_pointer_node
;
6597 source_length
= ffecom_f2c_ftnlen_zero_node
;
6598 expr_tree
= build_tree_list (NULL_TREE
, dest_tree
);
6599 TREE_CHAIN (expr_tree
) = build_tree_list (NULL_TREE
, source_tree
);
6600 TREE_CHAIN (TREE_CHAIN (expr_tree
))
6601 = build_tree_list (NULL_TREE
, dest_length
);
6602 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree
)))
6603 = build_tree_list (NULL_TREE
, source_length
);
6605 expr_tree
= ffecom_call_gfrt (FFECOM_gfrtCOPY
, expr_tree
, NULL_TREE
);
6606 TREE_SIDE_EFFECTS (expr_tree
) = 1;
6608 expand_expr_stmt (expr_tree
);
6612 case 1: /* The (fairly) easy case. */
6613 ffecom_char_args_ (&source_tree
, &source_length
,
6614 ffecom_concat_list_expr_ (catlist
, 0));
6615 ffecom_concat_list_kill_ (catlist
);
6616 assert (source_tree
!= NULL_TREE
);
6617 assert (source_length
!= NULL_TREE
);
6619 if ((source_tree
== error_mark_node
)
6620 || (source_length
== error_mark_node
))
6626 = ffecom_1 (INDIRECT_REF
,
6627 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6631 = ffecom_2 (ARRAY_REF
,
6632 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6637 = ffecom_1 (INDIRECT_REF
,
6638 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6642 = ffecom_2 (ARRAY_REF
,
6643 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6648 expr_tree
= ffecom_modify (void_type_node
, dest_tree
, source_tree
);
6650 expand_expr_stmt (expr_tree
);
6655 expr_tree
= build_tree_list (NULL_TREE
, dest_tree
);
6656 TREE_CHAIN (expr_tree
) = build_tree_list (NULL_TREE
, source_tree
);
6657 TREE_CHAIN (TREE_CHAIN (expr_tree
))
6658 = build_tree_list (NULL_TREE
, dest_length
);
6659 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree
)))
6660 = build_tree_list (NULL_TREE
, source_length
);
6662 expr_tree
= ffecom_call_gfrt (FFECOM_gfrtCOPY
, expr_tree
, NULL_TREE
);
6663 TREE_SIDE_EFFECTS (expr_tree
) = 1;
6665 expand_expr_stmt (expr_tree
);
6669 default: /* Must actually concatenate things. */
6673 /* Heavy-duty concatenation. */
6676 int count
= ffecom_concat_list_count_ (catlist
);
6688 hook
= ffebld_nonter_hook (source
);
6690 assert (TREE_CODE (hook
) == TREE_VEC
);
6691 assert (TREE_VEC_LENGTH (hook
) == 2);
6692 length_array
= lengths
= TREE_VEC_ELT (hook
, 0);
6693 item_array
= items
= TREE_VEC_ELT (hook
, 1);
6696 for (i
= 0; i
< count
; ++i
)
6698 ffecom_char_args_ (&citem
, &clength
,
6699 ffecom_concat_list_expr_ (catlist
, i
));
6700 if ((citem
== error_mark_node
)
6701 || (clength
== error_mark_node
))
6703 ffecom_concat_list_kill_ (catlist
);
6708 = ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (items
),
6709 ffecom_modify (void_type_node
,
6710 ffecom_2 (ARRAY_REF
,
6711 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array
))),
6713 build_int_2 (i
, 0)),
6717 = ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (lengths
),
6718 ffecom_modify (void_type_node
,
6719 ffecom_2 (ARRAY_REF
,
6720 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array
))),
6722 build_int_2 (i
, 0)),
6727 expr_tree
= build_tree_list (NULL_TREE
, dest_tree
);
6728 TREE_CHAIN (expr_tree
)
6729 = build_tree_list (NULL_TREE
,
6730 ffecom_1 (ADDR_EXPR
,
6731 build_pointer_type (TREE_TYPE (items
)),
6733 TREE_CHAIN (TREE_CHAIN (expr_tree
))
6734 = build_tree_list (NULL_TREE
,
6735 ffecom_1 (ADDR_EXPR
,
6736 build_pointer_type (TREE_TYPE (lengths
)),
6738 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree
)))
6741 ffecom_1 (ADDR_EXPR
, ffecom_f2c_ptr_to_ftnlen_type_node
,
6742 convert (ffecom_f2c_ftnlen_type_node
,
6743 build_int_2 (count
, 0))));
6744 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree
))))
6745 = build_tree_list (NULL_TREE
, dest_length
);
6747 expr_tree
= ffecom_call_gfrt (FFECOM_gfrtCAT
, expr_tree
, NULL_TREE
);
6748 TREE_SIDE_EFFECTS (expr_tree
) = 1;
6750 expand_expr_stmt (expr_tree
);
6753 ffecom_concat_list_kill_ (catlist
);
6756 /* ffecom_make_gfrt_ -- Make initial info for run-time routine
6759 ffecom_make_gfrt_(ix);
6761 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6762 for the indicated run-time routine (ix). */
6765 ffecom_make_gfrt_ (ffecomGfrt ix
)
6770 switch (ffecom_gfrt_type_
[ix
])
6772 case FFECOM_rttypeVOID_
:
6773 ttype
= void_type_node
;
6776 case FFECOM_rttypeVOIDSTAR_
:
6777 ttype
= TREE_TYPE (null_pointer_node
); /* `void *'. */
6780 case FFECOM_rttypeFTNINT_
:
6781 ttype
= ffecom_f2c_ftnint_type_node
;
6784 case FFECOM_rttypeINTEGER_
:
6785 ttype
= ffecom_f2c_integer_type_node
;
6788 case FFECOM_rttypeLONGINT_
:
6789 ttype
= ffecom_f2c_longint_type_node
;
6792 case FFECOM_rttypeLOGICAL_
:
6793 ttype
= ffecom_f2c_logical_type_node
;
6796 case FFECOM_rttypeREAL_F2C_
:
6797 ttype
= double_type_node
;
6800 case FFECOM_rttypeREAL_GNU_
:
6801 ttype
= float_type_node
;
6804 case FFECOM_rttypeCOMPLEX_F2C_
:
6805 ttype
= void_type_node
;
6808 case FFECOM_rttypeCOMPLEX_GNU_
:
6809 ttype
= ffecom_f2c_complex_type_node
;
6812 case FFECOM_rttypeDOUBLE_
:
6813 ttype
= double_type_node
;
6816 case FFECOM_rttypeDOUBLEREAL_
:
6817 ttype
= ffecom_f2c_doublereal_type_node
;
6820 case FFECOM_rttypeDBLCMPLX_F2C_
:
6821 ttype
= void_type_node
;
6824 case FFECOM_rttypeDBLCMPLX_GNU_
:
6825 ttype
= ffecom_f2c_doublecomplex_type_node
;
6828 case FFECOM_rttypeCHARACTER_
:
6829 ttype
= void_type_node
;
6834 assert ("bad rttype" == NULL
);
6838 ttype
= build_function_type (ttype
, NULL_TREE
);
6839 t
= build_decl (FUNCTION_DECL
,
6840 get_identifier (ffecom_gfrt_name_
[ix
]),
6842 DECL_EXTERNAL (t
) = 1;
6843 TREE_READONLY (t
) = ffecom_gfrt_const_
[ix
] ? 1 : 0;
6844 TREE_PUBLIC (t
) = 1;
6845 TREE_THIS_VOLATILE (t
) = ffecom_gfrt_volatile_
[ix
] ? 1 : 0;
6847 /* Sanity check: A function that's const cannot be volatile. */
6849 assert (ffecom_gfrt_const_
[ix
] ? !ffecom_gfrt_volatile_
[ix
] : 1);
6851 /* Sanity check: A function that's const cannot return complex. */
6853 assert (ffecom_gfrt_const_
[ix
] ? !ffecom_gfrt_complex_
[ix
] : 1);
6855 t
= start_decl (t
, TRUE
);
6857 finish_decl (t
, NULL_TREE
, TRUE
);
6859 ffecom_gfrt_
[ix
] = t
;
6862 /* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
6865 ffecom_member_phase1_ (ffestorag mst UNUSED
, ffestorag st
)
6867 ffesymbol s
= ffestorag_symbol (st
);
6869 if (ffesymbol_namelisted (s
))
6870 ffecom_member_namelisted_
= TRUE
;
6873 /* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
6874 the member so debugger will see it. Otherwise nobody should be
6875 referencing the member. */
6878 ffecom_member_phase2_ (ffestorag mst
, ffestorag st
)
6886 || ((mt
= ffestorag_hook (mst
)) == NULL
)
6887 || (mt
== error_mark_node
))
6891 || ((s
= ffestorag_symbol (st
)) == NULL
))
6894 type
= ffecom_type_localvar_ (s
,
6895 ffesymbol_basictype (s
),
6896 ffesymbol_kindtype (s
));
6897 if (type
== error_mark_node
)
6900 t
= build_decl (VAR_DECL
,
6901 ffecom_get_identifier_ (ffesymbol_text (s
)),
6904 TREE_STATIC (t
) = TREE_STATIC (mt
);
6905 DECL_INITIAL (t
) = NULL_TREE
;
6906 TREE_ASM_WRITTEN (t
) = 1;
6910 gen_rtx_MEM (TYPE_MODE (type
),
6911 plus_constant (XEXP (DECL_RTL (mt
), 0),
6912 ffestorag_modulo (mst
)
6913 + ffestorag_offset (st
)
6914 - ffestorag_offset (mst
))));
6916 t
= start_decl (t
, FALSE
);
6918 finish_decl (t
, NULL_TREE
, FALSE
);
6921 /* Prepare source expression for assignment into a destination perhaps known
6922 to be of a specific size. */
6925 ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size
, ffebld source
)
6927 ffecomConcatList_ catlist
;
6932 tree tempvar
= NULL_TREE
;
6934 while (ffebld_op (source
) == FFEBLD_opCONVERT
)
6935 source
= ffebld_left (source
);
6937 catlist
= ffecom_concat_list_new_ (source
, dest_size
);
6938 count
= ffecom_concat_list_count_ (catlist
);
6943 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node
,
6944 FFETARGET_charactersizeNONE
, count
);
6946 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node
,
6947 FFETARGET_charactersizeNONE
, count
);
6949 tempvar
= make_tree_vec (2);
6950 TREE_VEC_ELT (tempvar
, 0) = ltmp
;
6951 TREE_VEC_ELT (tempvar
, 1) = itmp
;
6954 for (i
= 0; i
< count
; ++i
)
6955 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist
, i
));
6957 ffecom_concat_list_kill_ (catlist
);
6961 ffebld_nonter_set_hook (source
, tempvar
);
6962 current_binding_level
->prep_state
= 1;
6966 /* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
6968 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
6969 (which generates their trees) and then their trees get push_parm_decl'd.
6971 The second arg is TRUE if the dummies are for a statement function, in
6972 which case lengths are not pushed for character arguments (since they are
6973 always known by both the caller and the callee, though the code allows
6974 for someday permitting CHAR*(*) stmtfunc dummies). */
6977 ffecom_push_dummy_decls_ (ffebld dummy_list
, bool stmtfunc
)
6984 ffecom_transform_only_dummies_
= TRUE
;
6986 /* First push the parms corresponding to actual dummy "contents". */
6988 for (dumlist
= dummy_list
; dumlist
!= NULL
; dumlist
= ffebld_trail (dumlist
))
6990 dummy
= ffebld_head (dumlist
);
6991 switch (ffebld_op (dummy
))
6995 continue; /* Forget alternate returns. */
7000 assert (ffebld_op (dummy
) == FFEBLD_opSYMTER
);
7001 s
= ffebld_symter (dummy
);
7002 parm
= ffesymbol_hook (s
).decl_tree
;
7003 if (parm
== NULL_TREE
)
7005 s
= ffecom_sym_transform_ (s
);
7006 parm
= ffesymbol_hook (s
).decl_tree
;
7007 assert (parm
!= NULL_TREE
);
7009 if (parm
!= error_mark_node
)
7010 push_parm_decl (parm
);
7013 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
7015 for (dumlist
= dummy_list
; dumlist
!= NULL
; dumlist
= ffebld_trail (dumlist
))
7017 dummy
= ffebld_head (dumlist
);
7018 switch (ffebld_op (dummy
))
7022 continue; /* Forget alternate returns, they mean
7028 s
= ffebld_symter (dummy
);
7029 if (ffesymbol_basictype (s
) != FFEINFO_basictypeCHARACTER
)
7030 continue; /* Only looking for CHARACTER arguments. */
7031 if (stmtfunc
&& (ffesymbol_size (s
) != FFETARGET_charactersizeNONE
))
7032 continue; /* Stmtfunc arg with known size needs no
7034 if (ffesymbol_kind (s
) != FFEINFO_kindENTITY
)
7035 continue; /* Only looking for variables and arrays. */
7036 parm
= ffesymbol_hook (s
).length_tree
;
7037 assert (parm
!= NULL_TREE
);
7038 if (parm
!= error_mark_node
)
7039 push_parm_decl (parm
);
7042 ffecom_transform_only_dummies_
= FALSE
;
7045 /* ffecom_start_progunit_ -- Beginning of program unit
7047 Does GNU back end stuff necessary to teach it about the start of its
7048 equivalent of a Fortran program unit. */
7051 ffecom_start_progunit_ (void)
7053 ffesymbol fn
= ffecom_primary_entry_
;
7055 tree id
; /* Identifier (name) of function. */
7056 tree type
; /* Type of function. */
7057 tree result
; /* Result of function. */
7058 ffeinfoBasictype bt
;
7062 ffeglobalType egt
= FFEGLOBAL_type
;
7065 bool altentries
= (ffecom_num_entrypoints_
!= 0);
7068 && (ffecom_primary_entry_kind_
== FFEINFO_kindFUNCTION
)
7069 && (ffecom_master_bt_
== FFEINFO_basictypeNONE
);
7070 bool main_program
= FALSE
;
7071 location_t old_loc
= input_location
;
7073 assert (fn
!= NULL
);
7074 assert (ffesymbol_hook (fn
).decl_tree
== NULL_TREE
);
7076 input_filename
= ffesymbol_where_filename (fn
);
7077 input_line
= ffesymbol_where_filelinenum (fn
);
7079 switch (ffecom_primary_entry_kind_
)
7081 case FFEINFO_kindPROGRAM
:
7082 main_program
= TRUE
;
7083 gt
= FFEGLOBAL_typeMAIN
;
7084 bt
= FFEINFO_basictypeNONE
;
7085 kt
= FFEINFO_kindtypeNONE
;
7086 type
= ffecom_tree_fun_type_void
;
7091 case FFEINFO_kindBLOCKDATA
:
7092 gt
= FFEGLOBAL_typeBDATA
;
7093 bt
= FFEINFO_basictypeNONE
;
7094 kt
= FFEINFO_kindtypeNONE
;
7095 type
= ffecom_tree_fun_type_void
;
7100 case FFEINFO_kindFUNCTION
:
7101 gt
= FFEGLOBAL_typeFUNC
;
7102 egt
= FFEGLOBAL_typeEXT
;
7103 bt
= ffesymbol_basictype (fn
);
7104 kt
= ffesymbol_kindtype (fn
);
7105 if (bt
== FFEINFO_basictypeNONE
)
7107 ffeimplic_establish_symbol (fn
);
7108 if (ffesymbol_funcresult (fn
) != NULL
)
7109 ffeimplic_establish_symbol (ffesymbol_funcresult (fn
));
7110 bt
= ffesymbol_basictype (fn
);
7111 kt
= ffesymbol_kindtype (fn
);
7115 charfunc
= cmplxfunc
= FALSE
;
7116 else if (bt
== FFEINFO_basictypeCHARACTER
)
7117 charfunc
= TRUE
, cmplxfunc
= FALSE
;
7118 else if ((bt
== FFEINFO_basictypeCOMPLEX
)
7119 && ffesymbol_is_f2c (fn
)
7121 charfunc
= FALSE
, cmplxfunc
= TRUE
;
7123 charfunc
= cmplxfunc
= FALSE
;
7125 if (multi
|| charfunc
)
7126 type
= ffecom_tree_fun_type_void
;
7127 else if (ffesymbol_is_f2c (fn
) && !altentries
)
7128 type
= ffecom_tree_fun_type
[bt
][kt
];
7130 type
= build_function_type (ffecom_tree_type
[bt
][kt
], NULL_TREE
);
7132 if ((type
== NULL_TREE
)
7133 || (TREE_TYPE (type
) == NULL_TREE
))
7134 type
= ffecom_tree_fun_type_void
; /* _sym_exec_transition. */
7137 case FFEINFO_kindSUBROUTINE
:
7138 gt
= FFEGLOBAL_typeSUBR
;
7139 egt
= FFEGLOBAL_typeEXT
;
7140 bt
= FFEINFO_basictypeNONE
;
7141 kt
= FFEINFO_kindtypeNONE
;
7142 if (ffecom_is_altreturning_
)
7143 type
= ffecom_tree_subr_type
;
7145 type
= ffecom_tree_fun_type_void
;
7151 assert ("say what??" == NULL
);
7153 case FFEINFO_kindANY
:
7154 gt
= FFEGLOBAL_typeANY
;
7155 bt
= FFEINFO_basictypeNONE
;
7156 kt
= FFEINFO_kindtypeNONE
;
7157 type
= error_mark_node
;
7165 id
= ffecom_get_invented_identifier ("__g77_masterfun_%s",
7166 ffesymbol_text (fn
));
7168 #if FFETARGET_isENFORCED_MAIN
7169 else if (main_program
)
7170 id
= get_identifier (FFETARGET_nameENFORCED_MAIN_NAME
);
7173 id
= ffecom_get_external_identifier_ (fn
);
7177 0, /* nested/inline */
7178 !altentries
); /* TREE_PUBLIC */
7180 TREE_USED (current_function_decl
) = 1; /* Avoid spurious warning if altentries. */
7183 && ((g
= ffesymbol_global (fn
)) != NULL
)
7184 && ((ffeglobal_type (g
) == gt
)
7185 || (ffeglobal_type (g
) == egt
)))
7187 ffeglobal_set_hook (g
, current_function_decl
);
7190 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7191 exec-transitioning needs current_function_decl to be filled in. So we
7192 do these things in two phases. */
7195 { /* 1st arg identifies which entrypoint. */
7196 ffecom_which_entrypoint_decl_
7197 = build_decl (PARM_DECL
,
7198 ffecom_get_invented_identifier ("__g77_%s",
7199 "which_entrypoint"),
7201 push_parm_decl (ffecom_which_entrypoint_decl_
);
7207 { /* Arg for result (return value). */
7212 type
= ffecom_tree_type
[FFEINFO_basictypeCHARACTER
][kt
];
7214 type
= ffecom_tree_type
[FFEINFO_basictypeCOMPLEX
][kt
];
7216 type
= ffecom_multi_type_node_
;
7218 result
= ffecom_get_invented_identifier ("__g77_%s", "result");
7220 /* Make length arg _and_ enhance type info for CHAR arg itself. */
7223 length
= ffecom_char_enhance_arg_ (&type
, fn
);
7225 length
= NULL_TREE
; /* Not ref'd if !charfunc. */
7227 type
= build_pointer_type (type
);
7228 result
= build_decl (PARM_DECL
, result
, type
);
7230 push_parm_decl (result
);
7232 ffecom_multi_retval_
= result
;
7234 ffecom_func_result_
= result
;
7238 push_parm_decl (length
);
7239 ffecom_func_length_
= length
;
7243 if (ffecom_primary_entry_is_proc_
)
7246 arglist
= ffecom_master_arglist_
;
7248 arglist
= ffesymbol_dummyargs (fn
);
7249 ffecom_push_dummy_decls_ (arglist
, FALSE
);
7252 if (TREE_CODE (current_function_decl
) != ERROR_MARK
)
7253 store_parm_decls (main_program
? 1 : 0);
7255 ffecom_start_compstmt ();
7256 /* Disallow temp vars at this level. */
7257 current_binding_level
->prep_state
= 2;
7259 input_location
= old_loc
;
7261 /* This handles any symbols still untransformed, in case -g specified.
7262 This used to be done in ffecom_finish_progunit, but it turns out to
7263 be necessary to do it here so that statement functions are
7264 expanded before code. But don't bother for BLOCK DATA. */
7266 if (ffecom_primary_entry_kind_
!= FFEINFO_kindBLOCKDATA
)
7267 ffesymbol_drive (ffecom_finish_symbol_transform_
);
7270 /* ffecom_sym_transform_ -- Transform FFE sym into backend sym
7273 ffecom_sym_transform_(s);
7275 The ffesymbol_hook info for s is updated with appropriate backend info
7279 ffecom_sym_transform_ (ffesymbol s
)
7281 tree t
; /* Transformed thingy. */
7282 tree tlen
; /* Length if CHAR*(*). */
7283 bool addr
; /* Is t the address of the thingy? */
7284 ffeinfoBasictype bt
;
7287 location_t old_loc
= input_location
;
7289 /* Must ensure special ASSIGN variables are declared at top of outermost
7290 block, else they'll end up in the innermost block when their first
7291 ASSIGN is seen, which leaves them out of scope when they're the
7292 subject of a GOTO or I/O statement.
7294 We make this variable even if -fugly-assign. Just let it go unused,
7295 in case it turns out there are cases where we really want to use this
7296 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
7298 if (! ffecom_transform_only_dummies_
7299 && ffesymbol_assigned (s
)
7300 && ! ffesymbol_hook (s
).assign_tree
)
7301 s
= ffecom_sym_transform_assign_ (s
);
7303 if (ffesymbol_sfdummyparent (s
) == NULL
)
7305 input_filename
= ffesymbol_where_filename (s
);
7306 input_line
= ffesymbol_where_filelinenum (s
);
7310 ffesymbol sf
= ffesymbol_sfdummyparent (s
);
7312 input_filename
= ffesymbol_where_filename (sf
);
7313 input_line
= ffesymbol_where_filelinenum (sf
);
7316 bt
= ffeinfo_basictype (ffebld_info (s
));
7317 kt
= ffeinfo_kindtype (ffebld_info (s
));
7323 switch (ffesymbol_kind (s
))
7325 case FFEINFO_kindNONE
:
7326 switch (ffesymbol_where (s
))
7328 case FFEINFO_whereDUMMY
: /* Subroutine or function. */
7329 assert (ffecom_transform_only_dummies_
);
7331 /* Before 0.4, this could be ENTITY/DUMMY, but see
7332 ffestu_sym_end_transition -- no longer true (in particular, if
7333 it could be an ENTITY, it _will_ be made one, so that
7334 possibility won't come through here). So we never make length
7335 arg for CHARACTER type. */
7337 t
= build_decl (PARM_DECL
,
7338 ffecom_get_identifier_ (ffesymbol_text (s
)),
7339 ffecom_tree_ptr_to_subr_type
);
7340 DECL_ARTIFICIAL (t
) = 1;
7344 case FFEINFO_whereGLOBAL
: /* Subroutine or function. */
7345 assert (!ffecom_transform_only_dummies_
);
7347 if (((g
= ffesymbol_global (s
)) != NULL
)
7348 && ((ffeglobal_type (g
) == FFEGLOBAL_typeSUBR
)
7349 || (ffeglobal_type (g
) == FFEGLOBAL_typeFUNC
)
7350 || (ffeglobal_type (g
) == FFEGLOBAL_typeEXT
))
7351 && (ffeglobal_hook (g
) != NULL_TREE
)
7352 && ffe_is_globals ())
7354 t
= ffeglobal_hook (g
);
7358 t
= build_decl (FUNCTION_DECL
,
7359 ffecom_get_external_identifier_ (s
),
7360 ffecom_tree_subr_type
); /* Assume subr. */
7361 DECL_EXTERNAL (t
) = 1;
7362 TREE_PUBLIC (t
) = 1;
7364 t
= start_decl (t
, FALSE
);
7365 finish_decl (t
, NULL_TREE
, FALSE
);
7368 && ((ffeglobal_type (g
) == FFEGLOBAL_typeSUBR
)
7369 || (ffeglobal_type (g
) == FFEGLOBAL_typeFUNC
)
7370 || (ffeglobal_type (g
) == FFEGLOBAL_typeEXT
)))
7371 ffeglobal_set_hook (g
, t
);
7373 ffecom_save_tree_forever (t
);
7378 assert ("NONE where unexpected" == NULL
);
7380 case FFEINFO_whereANY
:
7385 case FFEINFO_kindENTITY
:
7386 switch (ffeinfo_where (ffesymbol_info (s
)))
7389 case FFEINFO_whereCONSTANT
:
7390 /* ~~Debugging info needed? */
7391 assert (!ffecom_transform_only_dummies_
);
7392 t
= error_mark_node
; /* Shouldn't ever see this in expr. */
7395 case FFEINFO_whereLOCAL
:
7396 assert (!ffecom_transform_only_dummies_
);
7399 ffestorag st
= ffesymbol_storage (s
);
7402 type
= ffecom_type_localvar_ (s
, bt
, kt
);
7404 if (type
== error_mark_node
)
7406 t
= error_mark_node
;
7411 && (ffestorag_size (st
) == 0))
7413 t
= error_mark_node
;
7418 && (ffestorag_parent (st
) != NULL
))
7419 { /* Child of EQUIVALENCE parent. */
7422 ffetargetOffset offset
;
7424 est
= ffestorag_parent (st
);
7425 ffecom_transform_equiv_ (est
);
7427 et
= ffestorag_hook (est
);
7428 assert (et
!= NULL_TREE
);
7430 if (! TREE_STATIC (et
))
7431 put_var_into_stack (et
, /*rescan=*/true);
7433 offset
= ffestorag_modulo (est
)
7434 + ffestorag_offset (ffesymbol_storage (s
))
7435 - ffestorag_offset (est
);
7437 ffecom_debug_kludge_ (et
, "EQUIVALENCE", s
, type
, offset
);
7439 /* (t_type *) (((char *) &et) + offset) */
7441 t
= convert (string_type_node
, /* (char *) */
7442 ffecom_1 (ADDR_EXPR
,
7443 build_pointer_type (TREE_TYPE (et
)),
7445 t
= ffecom_2 (PLUS_EXPR
, TREE_TYPE (t
),
7447 build_int_2 (offset
, 0));
7448 t
= convert (build_pointer_type (type
),
7450 TREE_CONSTANT (t
) = staticp (et
);
7457 bool init
= ffesymbol_is_init (s
);
7459 t
= build_decl (VAR_DECL
,
7460 ffecom_get_identifier_ (ffesymbol_text (s
)),
7464 || ffesymbol_namelisted (s
)
7465 #ifdef FFECOM_sizeMAXSTACKITEM
7467 && (ffestorag_size (st
) > FFECOM_sizeMAXSTACKITEM
))
7469 || ((ffecom_primary_entry_kind_
!= FFEINFO_kindPROGRAM
)
7470 && (ffecom_primary_entry_kind_
7471 != FFEINFO_kindBLOCKDATA
)
7472 && (ffesymbol_is_save (s
) || ffe_is_saveall ())))
7473 TREE_STATIC (t
) = !ffesymbol_attr (s
, FFESYMBOL_attrADJUSTABLE
);
7475 TREE_STATIC (t
) = 0; /* No need to make static. */
7477 if (init
|| ffe_is_init_local_zero ())
7478 DECL_INITIAL (t
) = error_mark_node
;
7480 /* Keep -Wunused from complaining about var if it
7481 is used as sfunc arg or DATA implied-DO. */
7482 if (ffesymbol_attrs (s
) & FFESYMBOL_attrsSFARG
)
7483 DECL_IN_SYSTEM_HEADER (t
) = 1;
7485 t
= start_decl (t
, FALSE
);
7489 if (ffesymbol_init (s
) != NULL
)
7490 initexpr
= ffecom_expr (ffesymbol_init (s
));
7492 initexpr
= ffecom_init_zero_ (t
);
7494 else if (ffe_is_init_local_zero ())
7495 initexpr
= ffecom_init_zero_ (t
);
7497 initexpr
= NULL_TREE
; /* Not ref'd if !init. */
7499 finish_decl (t
, initexpr
, FALSE
);
7501 if (st
!= NULL
&& DECL_SIZE (t
) != error_mark_node
)
7503 assert (TREE_CODE (DECL_SIZE_UNIT (t
)) == INTEGER_CST
);
7504 assert (0 == compare_tree_int (DECL_SIZE_UNIT (t
),
7505 ffestorag_size (st
)));
7511 case FFEINFO_whereRESULT
:
7512 assert (!ffecom_transform_only_dummies_
);
7514 if (bt
== FFEINFO_basictypeCHARACTER
)
7515 { /* Result is already in list of dummies, use
7517 t
= ffecom_func_result_
;
7518 tlen
= ffecom_func_length_
;
7522 if ((ffecom_num_entrypoints_
== 0)
7523 && (bt
== FFEINFO_basictypeCOMPLEX
)
7524 && (ffesymbol_is_f2c (ffecom_primary_entry_
)))
7525 { /* Result is already in list of dummies, use
7527 t
= ffecom_func_result_
;
7531 if (ffecom_func_result_
!= NULL_TREE
)
7533 t
= ffecom_func_result_
;
7536 if ((ffecom_num_entrypoints_
!= 0)
7537 && (ffecom_master_bt_
== FFEINFO_basictypeNONE
))
7539 assert (ffecom_multi_retval_
!= NULL_TREE
);
7540 t
= ffecom_1 (INDIRECT_REF
, ffecom_multi_type_node_
,
7541 ffecom_multi_retval_
);
7542 t
= ffecom_2 (COMPONENT_REF
, ffecom_tree_type
[bt
][kt
],
7543 t
, ffecom_multi_fields_
[bt
][kt
]);
7548 t
= build_decl (VAR_DECL
,
7549 ffecom_get_identifier_ (ffesymbol_text (s
)),
7550 ffecom_tree_type
[bt
][kt
]);
7551 TREE_STATIC (t
) = 0; /* Put result on stack. */
7552 t
= start_decl (t
, FALSE
);
7553 finish_decl (t
, NULL_TREE
, FALSE
);
7555 ffecom_func_result_
= t
;
7559 case FFEINFO_whereDUMMY
:
7567 bool adjustable
= FALSE
; /* Conditionally adjustable? */
7569 type
= ffecom_tree_type
[bt
][kt
];
7570 if (ffesymbol_sfdummyparent (s
) != NULL
)
7572 if (current_function_decl
== ffecom_outer_function_decl_
)
7573 { /* Exec transition before sfunc
7574 context; get it later. */
7577 t
= ffecom_get_identifier_ (ffesymbol_text
7578 (ffesymbol_sfdummyparent (s
)));
7581 t
= ffecom_get_identifier_ (ffesymbol_text (s
));
7583 assert (ffecom_transform_only_dummies_
);
7585 old_sizes
= get_pending_sizes ();
7586 put_pending_sizes (old_sizes
);
7588 if (bt
== FFEINFO_basictypeCHARACTER
)
7589 tlen
= ffecom_char_enhance_arg_ (&type
, s
);
7590 type
= ffecom_check_size_overflow_ (s
, type
, TRUE
);
7592 for (dl
= ffesymbol_dims (s
); dl
!= NULL
; dl
= ffebld_trail (dl
))
7594 if (type
== error_mark_node
)
7597 dim
= ffebld_head (dl
);
7598 assert (ffebld_op (dim
) == FFEBLD_opBOUNDS
);
7599 if ((ffebld_left (dim
) == NULL
) || ffecom_doing_entry_
)
7600 low
= ffecom_integer_one_node
;
7602 low
= ffecom_expr (ffebld_left (dim
));
7603 assert (ffebld_right (dim
) != NULL
);
7604 if ((ffebld_op (ffebld_right (dim
)) == FFEBLD_opSTAR
)
7605 || ffecom_doing_entry_
)
7607 /* Used to just do high=low. But for ffecom_tree_
7608 canonize_ref_, it probably is important to correctly
7609 assess the size. E.g. given COMPLEX C(*),CFUNC and
7610 C(2)=CFUNC(C), overlap can happen, while it can't
7611 for, say, C(1)=CFUNC(C(2)). */
7612 /* Even more recently used to set to INT_MAX, but that
7613 broke when some overflow checking went into the back
7614 end. Now we just leave the upper bound unspecified. */
7618 high
= ffecom_expr (ffebld_right (dim
));
7620 /* Determine whether array is conditionally adjustable,
7621 to decide whether back-end magic is needed.
7623 Normally the front end uses the back-end function
7624 variable_size to wrap SAVE_EXPR's around expressions
7625 affecting the size/shape of an array so that the
7626 size/shape info doesn't change during execution
7627 of the compiled code even though variables and
7628 functions referenced in those expressions might.
7630 variable_size also makes sure those saved expressions
7631 get evaluated immediately upon entry to the
7632 compiled procedure -- the front end normally doesn't
7633 have to worry about that.
7635 However, there is a problem with this that affects
7636 g77's implementation of entry points, and that is
7637 that it is _not_ true that each invocation of the
7638 compiled procedure is permitted to evaluate
7639 array size/shape info -- because it is possible
7640 that, for some invocations, that info is invalid (in
7641 which case it is "promised" -- i.e. a violation of
7642 the Fortran standard -- that the compiled code
7643 won't reference the array or its size/shape
7644 during that particular invocation).
7646 To phrase this in C terms, consider this gcc function:
7648 void foo (int *n, float (*a)[*n])
7650 // a is "pointer to array ...", fyi.
7653 Suppose that, for some invocations, it is permitted
7654 for a caller of foo to do this:
7658 Now the _written_ code for foo can take such a call
7659 into account by either testing explicitly for whether
7660 (a == NULL) || (n == NULL) -- presumably it is
7661 not permitted to reference *a in various fashions
7662 if (n == NULL) I suppose -- or it can avoid it by
7663 looking at other info (other arguments, static/global
7666 However, this won't work in gcc 2.5.8 because it'll
7667 automatically emit the code to save the "*n"
7668 expression, which'll yield a NULL dereference for
7669 the "foo (NULL, NULL)" call, something the code
7670 for foo cannot prevent.
7672 g77 definitely needs to avoid executing such
7673 code anytime the pointer to the adjustable array
7674 is NULL, because even if its bounds expressions
7675 don't have any references to possible "absent"
7676 variables like "*n" -- say all variable references
7677 are to COMMON variables, i.e. global (though in C,
7678 local static could actually make sense) -- the
7679 expressions could yield other run-time problems
7680 for allowably "dead" values in those variables.
7682 For example, let's consider a more complicated
7688 void foo (float (*a)[i/j])
7693 The above is (essentially) quite valid for Fortran
7694 but, again, for a call like "foo (NULL);", it is
7695 permitted for i and j to be undefined when the
7696 call is made. If j happened to be zero, for
7697 example, emitting the code to evaluate "i/j"
7698 could result in a run-time error.
7700 Offhand, though I don't have my F77 or F90
7701 standards handy, it might even be valid for a
7702 bounds expression to contain a function reference,
7703 in which case I doubt it is permitted for an
7704 implementation to invoke that function in the
7705 Fortran case involved here (invocation of an
7706 alternate ENTRY point that doesn't have the adjustable
7707 array as one of its arguments).
7709 So, the code that the compiler would normally emit
7710 to preevaluate the size/shape info for an
7711 adjustable array _must not_ be executed at run time
7712 in certain cases. Specifically, for Fortran,
7713 the case is when the pointer to the adjustable
7714 array == NULL. (For gnu-ish C, it might be nice
7715 for the source code itself to specify an expression
7716 that, if TRUE, inhibits execution of the code. Or
7717 reverse the sense for elegance.)
7719 (Note that g77 could use a different test than NULL,
7720 actually, since it happens to always pass an
7721 integer to the called function that specifies which
7722 entry point is being invoked. Hmm, this might
7723 solve the next problem.)
7725 One way a user could, I suppose, write "foo" so
7726 it works is to insert COND_EXPR's for the
7727 size/shape info so the dangerous stuff isn't
7728 actually done, as in:
7730 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7735 The next problem is that the front end needs to
7736 be able to tell the back end about the array's
7737 decl _before_ it tells it about the conditional
7738 expression to inhibit evaluation of size/shape info,
7741 To solve this, the front end needs to be able
7742 to give the back end the expression to inhibit
7743 generation of the preevaluation code _after_
7744 it makes the decl for the adjustable array.
7746 Until then, the above example using the COND_EXPR
7747 doesn't pass muster with gcc because the "(a == NULL)"
7748 part has a reference to "a", which is still
7749 undefined at that point.
7751 g77 will therefore use a different mechanism in the
7755 && ((TREE_CODE (low
) != INTEGER_CST
)
7756 || (high
&& TREE_CODE (high
) != INTEGER_CST
)))
7759 #if 0 /* Old approach -- see below. */
7760 if (TREE_CODE (low
) != INTEGER_CST
)
7761 low
= ffecom_3 (COND_EXPR
, integer_type_node
,
7762 ffecom_adjarray_passed_ (s
),
7764 ffecom_integer_zero_node
);
7766 if (high
&& TREE_CODE (high
) != INTEGER_CST
)
7767 high
= ffecom_3 (COND_EXPR
, integer_type_node
,
7768 ffecom_adjarray_passed_ (s
),
7770 ffecom_integer_zero_node
);
7773 /* ~~~gcc/stor-layout.c (layout_type) should do this,
7774 probably. Fixes 950302-1.f. */
7776 if (TREE_CODE (low
) != INTEGER_CST
)
7777 low
= variable_size (low
);
7779 /* ~~~Similarly, this fixes dumb0.f. The C front end
7780 does this, which is why dumb0.c would work. */
7782 if (high
&& TREE_CODE (high
) != INTEGER_CST
)
7783 high
= variable_size (high
);
7788 build_range_type (ffecom_integer_type_node
,
7790 type
= ffecom_check_size_overflow_ (s
, type
, TRUE
);
7793 if (type
== error_mark_node
)
7795 t
= error_mark_node
;
7799 if ((ffesymbol_sfdummyparent (s
) == NULL
)
7800 || (ffesymbol_basictype (s
) == FFEINFO_basictypeCHARACTER
))
7802 type
= build_pointer_type (type
);
7806 t
= build_decl (PARM_DECL
, t
, type
);
7807 DECL_ARTIFICIAL (t
) = 1;
7809 /* If this arg is present in every entry point's list of
7810 dummy args, then we're done. */
7812 if (ffesymbol_numentries (s
)
7813 == (ffecom_num_entrypoints_
+ 1))
7818 /* If variable_size in stor-layout has been called during
7819 the above, then get_pending_sizes should have the
7820 yet-to-be-evaluated saved expressions pending.
7821 Make the whole lot of them get emitted, conditionally
7822 on whether the array decl ("t" above) is not NULL. */
7825 tree sizes
= get_pending_sizes ();
7830 tem
= TREE_CHAIN (tem
))
7832 tree temv
= TREE_VALUE (tem
);
7838 = ffecom_2 (COMPOUND_EXPR
,
7847 = ffecom_3 (COND_EXPR
,
7854 convert (TREE_TYPE (sizes
),
7855 integer_zero_node
));
7856 sizes
= ffecom_save_tree (sizes
);
7859 = tree_cons (NULL_TREE
, sizes
, tem
);
7863 put_pending_sizes (sizes
);
7869 && (ffesymbol_numentries (s
)
7870 != ffecom_num_entrypoints_
+ 1))
7872 = ffecom_2 (NE_EXPR
, integer_type_node
,
7878 && (ffesymbol_numentries (s
)
7879 != ffecom_num_entrypoints_
+ 1))
7881 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED
);
7882 ffebad_here (0, ffesymbol_where_line (s
),
7883 ffesymbol_where_column (s
));
7884 ffebad_string (ffesymbol_text (s
));
7893 case FFEINFO_whereCOMMON
:
7898 ffestorag st
= ffesymbol_storage (s
);
7901 cs
= ffesymbol_common (s
); /* The COMMON area itself. */
7902 if (st
!= NULL
) /* Else not laid out. */
7904 ffecom_transform_common_ (cs
);
7905 st
= ffesymbol_storage (s
);
7908 type
= ffecom_type_localvar_ (s
, bt
, kt
);
7910 cg
= ffesymbol_global (cs
); /* The global COMMON info. */
7912 || (ffeglobal_type (cg
) != FFEGLOBAL_typeCOMMON
))
7915 ct
= ffeglobal_hook (cg
); /* The common area's tree. */
7917 if ((ct
== NULL_TREE
)
7919 || (type
== error_mark_node
))
7920 t
= error_mark_node
;
7923 ffetargetOffset offset
;
7927 cst
= ffestorag_parent (st
);
7928 assert (cst
== ffesymbol_storage (cs
));
7930 offset
= ffestorag_modulo (cst
)
7931 + ffestorag_offset (st
)
7932 - ffestorag_offset (cst
);
7934 ffecom_debug_kludge_ (ct
, "COMMON", s
, type
, offset
);
7936 /* (t_type *) (((char *) &ct) + offset) */
7938 t
= convert (string_type_node
, /* (char *) */
7939 ffecom_1 (ADDR_EXPR
,
7940 build_pointer_type (TREE_TYPE (ct
)),
7942 toffset
= build_int_2 (offset
, 0);
7943 TREE_TYPE (toffset
) = ssizetype
;
7944 t
= ffecom_2 (PLUS_EXPR
, TREE_TYPE (t
),
7946 t
= convert (build_pointer_type (type
),
7948 TREE_CONSTANT (t
) = 1;
7955 case FFEINFO_whereIMMEDIATE
:
7956 case FFEINFO_whereGLOBAL
:
7957 case FFEINFO_whereFLEETING
:
7958 case FFEINFO_whereFLEETING_CADDR
:
7959 case FFEINFO_whereFLEETING_IADDR
:
7960 case FFEINFO_whereINTRINSIC
:
7961 case FFEINFO_whereCONSTANT_SUBOBJECT
:
7963 assert ("ENTITY where unheard of" == NULL
);
7965 case FFEINFO_whereANY
:
7966 t
= error_mark_node
;
7971 case FFEINFO_kindFUNCTION
:
7972 switch (ffeinfo_where (ffesymbol_info (s
)))
7974 case FFEINFO_whereLOCAL
: /* Me. */
7975 assert (!ffecom_transform_only_dummies_
);
7976 t
= current_function_decl
;
7979 case FFEINFO_whereGLOBAL
:
7980 assert (!ffecom_transform_only_dummies_
);
7982 if (((g
= ffesymbol_global (s
)) != NULL
)
7983 && ((ffeglobal_type (g
) == FFEGLOBAL_typeFUNC
)
7984 || (ffeglobal_type (g
) == FFEGLOBAL_typeEXT
))
7985 && (ffeglobal_hook (g
) != NULL_TREE
)
7986 && ffe_is_globals ())
7988 t
= ffeglobal_hook (g
);
7992 if (ffesymbol_is_f2c (s
)
7993 && (ffesymbol_where (s
) != FFEINFO_whereCONSTANT
))
7994 t
= ffecom_tree_fun_type
[bt
][kt
];
7996 t
= build_function_type (ffecom_tree_type
[bt
][kt
], NULL_TREE
);
7998 t
= build_decl (FUNCTION_DECL
,
7999 ffecom_get_external_identifier_ (s
),
8001 DECL_EXTERNAL (t
) = 1;
8002 TREE_PUBLIC (t
) = 1;
8004 t
= start_decl (t
, FALSE
);
8005 finish_decl (t
, NULL_TREE
, FALSE
);
8008 && ((ffeglobal_type (g
) == FFEGLOBAL_typeFUNC
)
8009 || (ffeglobal_type (g
) == FFEGLOBAL_typeEXT
)))
8010 ffeglobal_set_hook (g
, t
);
8012 ffecom_save_tree_forever (t
);
8016 case FFEINFO_whereDUMMY
:
8017 assert (ffecom_transform_only_dummies_
);
8019 if (ffesymbol_is_f2c (s
)
8020 && (ffesymbol_where (s
) != FFEINFO_whereCONSTANT
))
8021 t
= ffecom_tree_ptr_to_fun_type
[bt
][kt
];
8023 t
= build_pointer_type
8024 (build_function_type (ffecom_tree_type
[bt
][kt
], NULL_TREE
));
8026 t
= build_decl (PARM_DECL
,
8027 ffecom_get_identifier_ (ffesymbol_text (s
)),
8029 DECL_ARTIFICIAL (t
) = 1;
8033 case FFEINFO_whereCONSTANT
: /* Statement function. */
8034 assert (!ffecom_transform_only_dummies_
);
8035 t
= ffecom_gen_sfuncdef_ (s
, bt
, kt
);
8038 case FFEINFO_whereINTRINSIC
:
8039 assert (!ffecom_transform_only_dummies_
);
8040 break; /* Let actual references generate their
8044 assert ("FUNCTION where unheard of" == NULL
);
8046 case FFEINFO_whereANY
:
8047 t
= error_mark_node
;
8052 case FFEINFO_kindSUBROUTINE
:
8053 switch (ffeinfo_where (ffesymbol_info (s
)))
8055 case FFEINFO_whereLOCAL
: /* Me. */
8056 assert (!ffecom_transform_only_dummies_
);
8057 t
= current_function_decl
;
8060 case FFEINFO_whereGLOBAL
:
8061 assert (!ffecom_transform_only_dummies_
);
8063 if (((g
= ffesymbol_global (s
)) != NULL
)
8064 && ((ffeglobal_type (g
) == FFEGLOBAL_typeSUBR
)
8065 || (ffeglobal_type (g
) == FFEGLOBAL_typeEXT
))
8066 && (ffeglobal_hook (g
) != NULL_TREE
)
8067 && ffe_is_globals ())
8069 t
= ffeglobal_hook (g
);
8073 t
= build_decl (FUNCTION_DECL
,
8074 ffecom_get_external_identifier_ (s
),
8075 ffecom_tree_subr_type
);
8076 DECL_EXTERNAL (t
) = 1;
8077 TREE_PUBLIC (t
) = 1;
8079 t
= start_decl (t
, ffe_is_globals ());
8080 finish_decl (t
, NULL_TREE
, ffe_is_globals ());
8083 && ((ffeglobal_type (g
) == FFEGLOBAL_typeSUBR
)
8084 || (ffeglobal_type (g
) == FFEGLOBAL_typeEXT
)))
8085 ffeglobal_set_hook (g
, t
);
8087 ffecom_save_tree_forever (t
);
8091 case FFEINFO_whereDUMMY
:
8092 assert (ffecom_transform_only_dummies_
);
8094 t
= build_decl (PARM_DECL
,
8095 ffecom_get_identifier_ (ffesymbol_text (s
)),
8096 ffecom_tree_ptr_to_subr_type
);
8097 DECL_ARTIFICIAL (t
) = 1;
8101 case FFEINFO_whereINTRINSIC
:
8102 assert (!ffecom_transform_only_dummies_
);
8103 break; /* Let actual references generate their
8107 assert ("SUBROUTINE where unheard of" == NULL
);
8109 case FFEINFO_whereANY
:
8110 t
= error_mark_node
;
8115 case FFEINFO_kindPROGRAM
:
8116 switch (ffeinfo_where (ffesymbol_info (s
)))
8118 case FFEINFO_whereLOCAL
: /* Me. */
8119 assert (!ffecom_transform_only_dummies_
);
8120 t
= current_function_decl
;
8123 case FFEINFO_whereCOMMON
:
8124 case FFEINFO_whereDUMMY
:
8125 case FFEINFO_whereGLOBAL
:
8126 case FFEINFO_whereRESULT
:
8127 case FFEINFO_whereFLEETING
:
8128 case FFEINFO_whereFLEETING_CADDR
:
8129 case FFEINFO_whereFLEETING_IADDR
:
8130 case FFEINFO_whereIMMEDIATE
:
8131 case FFEINFO_whereINTRINSIC
:
8132 case FFEINFO_whereCONSTANT
:
8133 case FFEINFO_whereCONSTANT_SUBOBJECT
:
8135 assert ("PROGRAM where unheard of" == NULL
);
8137 case FFEINFO_whereANY
:
8138 t
= error_mark_node
;
8143 case FFEINFO_kindBLOCKDATA
:
8144 switch (ffeinfo_where (ffesymbol_info (s
)))
8146 case FFEINFO_whereLOCAL
: /* Me. */
8147 assert (!ffecom_transform_only_dummies_
);
8148 t
= current_function_decl
;
8151 case FFEINFO_whereGLOBAL
:
8152 assert (!ffecom_transform_only_dummies_
);
8154 t
= build_decl (FUNCTION_DECL
,
8155 ffecom_get_external_identifier_ (s
),
8156 ffecom_tree_blockdata_type
);
8157 DECL_EXTERNAL (t
) = 1;
8158 TREE_PUBLIC (t
) = 1;
8160 t
= start_decl (t
, FALSE
);
8161 finish_decl (t
, NULL_TREE
, FALSE
);
8163 ffecom_save_tree_forever (t
);
8167 case FFEINFO_whereCOMMON
:
8168 case FFEINFO_whereDUMMY
:
8169 case FFEINFO_whereRESULT
:
8170 case FFEINFO_whereFLEETING
:
8171 case FFEINFO_whereFLEETING_CADDR
:
8172 case FFEINFO_whereFLEETING_IADDR
:
8173 case FFEINFO_whereIMMEDIATE
:
8174 case FFEINFO_whereINTRINSIC
:
8175 case FFEINFO_whereCONSTANT
:
8176 case FFEINFO_whereCONSTANT_SUBOBJECT
:
8178 assert ("BLOCKDATA where unheard of" == NULL
);
8180 case FFEINFO_whereANY
:
8181 t
= error_mark_node
;
8186 case FFEINFO_kindCOMMON
:
8187 switch (ffeinfo_where (ffesymbol_info (s
)))
8189 case FFEINFO_whereLOCAL
:
8190 assert (!ffecom_transform_only_dummies_
);
8191 ffecom_transform_common_ (s
);
8194 case FFEINFO_whereNONE
:
8195 case FFEINFO_whereCOMMON
:
8196 case FFEINFO_whereDUMMY
:
8197 case FFEINFO_whereGLOBAL
:
8198 case FFEINFO_whereRESULT
:
8199 case FFEINFO_whereFLEETING
:
8200 case FFEINFO_whereFLEETING_CADDR
:
8201 case FFEINFO_whereFLEETING_IADDR
:
8202 case FFEINFO_whereIMMEDIATE
:
8203 case FFEINFO_whereINTRINSIC
:
8204 case FFEINFO_whereCONSTANT
:
8205 case FFEINFO_whereCONSTANT_SUBOBJECT
:
8207 assert ("COMMON where unheard of" == NULL
);
8209 case FFEINFO_whereANY
:
8210 t
= error_mark_node
;
8215 case FFEINFO_kindCONSTRUCT
:
8216 switch (ffeinfo_where (ffesymbol_info (s
)))
8218 case FFEINFO_whereLOCAL
:
8219 assert (!ffecom_transform_only_dummies_
);
8222 case FFEINFO_whereNONE
:
8223 case FFEINFO_whereCOMMON
:
8224 case FFEINFO_whereDUMMY
:
8225 case FFEINFO_whereGLOBAL
:
8226 case FFEINFO_whereRESULT
:
8227 case FFEINFO_whereFLEETING
:
8228 case FFEINFO_whereFLEETING_CADDR
:
8229 case FFEINFO_whereFLEETING_IADDR
:
8230 case FFEINFO_whereIMMEDIATE
:
8231 case FFEINFO_whereINTRINSIC
:
8232 case FFEINFO_whereCONSTANT
:
8233 case FFEINFO_whereCONSTANT_SUBOBJECT
:
8235 assert ("CONSTRUCT where unheard of" == NULL
);
8237 case FFEINFO_whereANY
:
8238 t
= error_mark_node
;
8243 case FFEINFO_kindNAMELIST
:
8244 switch (ffeinfo_where (ffesymbol_info (s
)))
8246 case FFEINFO_whereLOCAL
:
8247 assert (!ffecom_transform_only_dummies_
);
8248 t
= ffecom_transform_namelist_ (s
);
8251 case FFEINFO_whereNONE
:
8252 case FFEINFO_whereCOMMON
:
8253 case FFEINFO_whereDUMMY
:
8254 case FFEINFO_whereGLOBAL
:
8255 case FFEINFO_whereRESULT
:
8256 case FFEINFO_whereFLEETING
:
8257 case FFEINFO_whereFLEETING_CADDR
:
8258 case FFEINFO_whereFLEETING_IADDR
:
8259 case FFEINFO_whereIMMEDIATE
:
8260 case FFEINFO_whereINTRINSIC
:
8261 case FFEINFO_whereCONSTANT
:
8262 case FFEINFO_whereCONSTANT_SUBOBJECT
:
8264 assert ("NAMELIST where unheard of" == NULL
);
8266 case FFEINFO_whereANY
:
8267 t
= error_mark_node
;
8273 assert ("kind unheard of" == NULL
);
8275 case FFEINFO_kindANY
:
8276 t
= error_mark_node
;
8280 ffesymbol_hook (s
).decl_tree
= t
;
8281 ffesymbol_hook (s
).length_tree
= tlen
;
8282 ffesymbol_hook (s
).addr
= addr
;
8284 input_location
= old_loc
;
8289 /* Transform into ASSIGNable symbol.
8291 Symbol has already been transformed, but for whatever reason, the
8292 resulting decl_tree has been deemed not usable for an ASSIGN target.
8293 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8294 another local symbol of type void * and stuff that in the assign_tree
8295 argument. The F77/F90 standards allow this implementation. */
8298 ffecom_sym_transform_assign_ (ffesymbol s
)
8300 tree t
; /* Transformed thingy. */
8301 location_t old_loc
= input_location
;
8303 if (ffesymbol_sfdummyparent (s
) == NULL
)
8305 input_filename
= ffesymbol_where_filename (s
);
8306 input_line
= ffesymbol_where_filelinenum (s
);
8310 ffesymbol sf
= ffesymbol_sfdummyparent (s
);
8312 input_filename
= ffesymbol_where_filename (sf
);
8313 input_line
= ffesymbol_where_filelinenum (sf
);
8316 assert (!ffecom_transform_only_dummies_
);
8318 t
= build_decl (VAR_DECL
,
8319 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
8320 ffesymbol_text (s
)),
8321 TREE_TYPE (null_pointer_node
));
8323 switch (ffesymbol_where (s
))
8325 case FFEINFO_whereLOCAL
:
8326 /* Unlike for regular vars, SAVE status is easy to determine for
8327 ASSIGNed vars, since there's no initialization, there's no
8328 effective storage association (so "SAVE J" does not apply to
8329 K even given "EQUIVALENCE (J,K)"), there's no size issue
8330 to worry about, etc. */
8331 if ((ffesymbol_is_save (s
) || ffe_is_saveall ())
8332 && (ffecom_primary_entry_kind_
!= FFEINFO_kindPROGRAM
)
8333 && (ffecom_primary_entry_kind_
!= FFEINFO_kindBLOCKDATA
))
8334 TREE_STATIC (t
) = 1; /* SAVEd in proc, make static. */
8336 TREE_STATIC (t
) = 0; /* No need to make static. */
8339 case FFEINFO_whereCOMMON
:
8340 TREE_STATIC (t
) = 1; /* Assume COMMONs always SAVEd. */
8343 case FFEINFO_whereDUMMY
:
8344 /* Note that twinning a DUMMY means the caller won't see
8345 the ASSIGNed value. But both F77 and F90 allow implementations
8346 to do this, i.e. disallow Fortran code that would try and
8347 take advantage of actually putting a label into a variable
8348 via a dummy argument (or any other storage association, for
8350 TREE_STATIC (t
) = 0;
8354 TREE_STATIC (t
) = 0;
8358 t
= start_decl (t
, FALSE
);
8359 finish_decl (t
, NULL_TREE
, FALSE
);
8361 ffesymbol_hook (s
).assign_tree
= t
;
8363 input_location
= old_loc
;
8368 /* Implement COMMON area in back end.
8370 Because COMMON-based variables can be referenced in the dimension
8371 expressions of dummy (adjustable) arrays, and because dummies
8372 (in the gcc back end) need to be put in the outer binding level
8373 of a function (which has two binding levels, the outer holding
8374 the dummies and the inner holding the other vars), special care
8375 must be taken to handle COMMON areas.
8377 The current strategy is basically to always tell the back end about
8378 the COMMON area as a top-level external reference to just a block
8379 of storage of the master type of that area (e.g. integer, real,
8380 character, whatever -- not a structure). As a distinct action,
8381 if initial values are provided, tell the back end about the area
8382 as a top-level non-external (initialized) area and remember not to
8383 allow further initialization or expansion of the area. Meanwhile,
8384 if no initialization happens at all, tell the back end about
8385 the largest size we've seen declared so the space does get reserved.
8386 (This function doesn't handle all that stuff, but it does some
8387 of the important things.)
8389 Meanwhile, for COMMON variables themselves, just keep creating
8390 references like *((float *) (&common_area + offset)) each time
8391 we reference the variable. In other words, don't make a VAR_DECL
8392 or any kind of component reference (like we used to do before 0.4),
8393 though we might do that as well just for debugging purposes (and
8394 stuff the rtl with the appropriate offset expression). */
8397 ffecom_transform_common_ (ffesymbol s
)
8399 ffestorag st
= ffesymbol_storage (s
);
8400 ffeglobal g
= ffesymbol_global (s
);
8405 bool is_init
= ffestorag_is_init (st
);
8407 assert (st
!= NULL
);
8410 || (ffeglobal_type (g
) != FFEGLOBAL_typeCOMMON
))
8413 /* First update the size of the area in global terms. */
8415 ffeglobal_size_common (s
, ffestorag_size (st
));
8417 if (!ffeglobal_common_init (g
))
8418 is_init
= FALSE
; /* No explicit init, don't let erroneous joins init. */
8420 cbt
= ffeglobal_hook (g
);
8422 /* If we already have declared this common block for a previous program
8423 unit, and either we already initialized it or we don't have new
8424 initialization for it, just return what we have without changing it. */
8426 if ((cbt
!= NULL_TREE
)
8428 || !DECL_EXTERNAL (cbt
)))
8430 if (st
->hook
== NULL
) ffestorag_set_hook (st
, cbt
);
8434 /* Process inits. */
8438 if (ffestorag_init (st
) != NULL
)
8442 /* Set the padding for the expression, so ffecom_expr
8443 knows to insert that many zeros. */
8444 switch (ffebld_op (sexp
= ffestorag_init (st
)))
8446 case FFEBLD_opCONTER
:
8447 ffebld_conter_set_pad (sexp
, ffestorag_modulo (st
));
8450 case FFEBLD_opARRTER
:
8451 ffebld_arrter_set_pad (sexp
, ffestorag_modulo (st
));
8454 case FFEBLD_opACCTER
:
8455 ffebld_accter_set_pad (sexp
, ffestorag_modulo (st
));
8459 assert ("bad op for cmn init (pad)" == NULL
);
8463 init
= ffecom_expr (sexp
);
8464 if (init
== error_mark_node
)
8465 { /* Hopefully the back end complained! */
8467 if (cbt
!= NULL_TREE
)
8472 init
= error_mark_node
;
8477 /* cbtype must be permanently allocated! */
8479 /* Allocate the MAX of the areas so far, seen filewide. */
8480 high
= build_int_2 ((ffeglobal_common_size (g
)
8481 + ffeglobal_common_pad (g
)) - 1, 0);
8482 TREE_TYPE (high
) = ffecom_integer_type_node
;
8485 cbtype
= build_array_type (char_type_node
,
8486 build_range_type (integer_type_node
,
8490 cbtype
= build_array_type (char_type_node
, NULL_TREE
);
8492 if (cbt
== NULL_TREE
)
8495 = build_decl (VAR_DECL
,
8496 ffecom_get_external_identifier_ (s
),
8498 TREE_STATIC (cbt
) = 1;
8499 TREE_PUBLIC (cbt
) = 1;
8504 TREE_TYPE (cbt
) = cbtype
;
8506 DECL_EXTERNAL (cbt
) = init
? 0 : 1;
8507 DECL_INITIAL (cbt
) = init
? error_mark_node
: NULL_TREE
;
8509 cbt
= start_decl (cbt
, TRUE
);
8510 if (ffeglobal_hook (g
) != NULL
)
8511 assert (cbt
== ffeglobal_hook (g
));
8513 assert (!init
|| !DECL_EXTERNAL (cbt
));
8515 /* Make sure that any type can live in COMMON and be referenced
8516 without getting a bus error. We could pick the most restrictive
8517 alignment of all entities actually placed in the COMMON, but
8518 this seems easy enough. */
8520 DECL_ALIGN (cbt
) = BIGGEST_ALIGNMENT
;
8521 DECL_USER_ALIGN (cbt
) = 0;
8523 if (is_init
&& (ffestorag_init (st
) == NULL
))
8524 init
= ffecom_init_zero_ (cbt
);
8526 finish_decl (cbt
, init
, TRUE
);
8529 ffestorag_set_init (st
, ffebld_new_any ());
8533 assert (DECL_SIZE_UNIT (cbt
) != NULL_TREE
);
8534 assert (TREE_CODE (DECL_SIZE_UNIT (cbt
)) == INTEGER_CST
);
8535 assert (0 == compare_tree_int (DECL_SIZE_UNIT (cbt
),
8536 (ffeglobal_common_size (g
)
8537 + ffeglobal_common_pad (g
))));
8540 ffeglobal_set_hook (g
, cbt
);
8542 ffestorag_set_hook (st
, cbt
);
8544 ffecom_save_tree_forever (cbt
);
8547 /* Make master area for local EQUIVALENCE. */
8550 ffecom_transform_equiv_ (ffestorag eqst
)
8556 bool is_init
= ffestorag_is_init (eqst
);
8558 assert (eqst
!= NULL
);
8560 eqt
= ffestorag_hook (eqst
);
8562 if (eqt
!= NULL_TREE
)
8565 /* Process inits. */
8569 if (ffestorag_init (eqst
) != NULL
)
8573 /* Set the padding for the expression, so ffecom_expr
8574 knows to insert that many zeros. */
8575 switch (ffebld_op (sexp
= ffestorag_init (eqst
)))
8577 case FFEBLD_opCONTER
:
8578 ffebld_conter_set_pad (sexp
, ffestorag_modulo (eqst
));
8581 case FFEBLD_opARRTER
:
8582 ffebld_arrter_set_pad (sexp
, ffestorag_modulo (eqst
));
8585 case FFEBLD_opACCTER
:
8586 ffebld_accter_set_pad (sexp
, ffestorag_modulo (eqst
));
8590 assert ("bad op for eqv init (pad)" == NULL
);
8594 init
= ffecom_expr (sexp
);
8595 if (init
== error_mark_node
)
8596 init
= NULL_TREE
; /* Hopefully the back end complained! */
8599 init
= error_mark_node
;
8601 else if (ffe_is_init_local_zero ())
8602 init
= error_mark_node
;
8606 ffecom_member_namelisted_
= FALSE
;
8607 ffestorag_drive (ffestorag_list_equivs (eqst
),
8608 &ffecom_member_phase1_
,
8611 high
= build_int_2 ((ffestorag_size (eqst
)
8612 + ffestorag_modulo (eqst
)) - 1, 0);
8613 TREE_TYPE (high
) = ffecom_integer_type_node
;
8615 eqtype
= build_array_type (char_type_node
,
8616 build_range_type (ffecom_integer_type_node
,
8617 ffecom_integer_zero_node
,
8620 eqt
= build_decl (VAR_DECL
,
8621 ffecom_get_invented_identifier ("__g77_equiv_%s",
8623 (ffestorag_symbol (eqst
))),
8625 DECL_EXTERNAL (eqt
) = 0;
8627 || ffecom_member_namelisted_
8628 #ifdef FFECOM_sizeMAXSTACKITEM
8629 || (ffestorag_size (eqst
) > FFECOM_sizeMAXSTACKITEM
)
8631 || ((ffecom_primary_entry_kind_
!= FFEINFO_kindPROGRAM
)
8632 && (ffecom_primary_entry_kind_
!= FFEINFO_kindBLOCKDATA
)
8633 && (ffestorag_is_save (eqst
) || ffe_is_saveall ())))
8634 TREE_STATIC (eqt
) = 1;
8636 TREE_STATIC (eqt
) = 0;
8637 TREE_PUBLIC (eqt
) = 0;
8638 TREE_ADDRESSABLE (eqt
) = 1; /* Ensure non-register allocation */
8639 DECL_CONTEXT (eqt
) = current_function_decl
;
8641 DECL_INITIAL (eqt
) = error_mark_node
;
8643 DECL_INITIAL (eqt
) = NULL_TREE
;
8645 eqt
= start_decl (eqt
, FALSE
);
8647 /* Make sure that any type can live in EQUIVALENCE and be referenced
8648 without getting a bus error. We could pick the most restrictive
8649 alignment of all entities actually placed in the EQUIVALENCE, but
8650 this seems easy enough. */
8652 DECL_ALIGN (eqt
) = BIGGEST_ALIGNMENT
;
8653 DECL_USER_ALIGN (eqt
) = 0;
8655 if ((!is_init
&& ffe_is_init_local_zero ())
8656 || (is_init
&& (ffestorag_init (eqst
) == NULL
)))
8657 init
= ffecom_init_zero_ (eqt
);
8659 finish_decl (eqt
, init
, FALSE
);
8662 ffestorag_set_init (eqst
, ffebld_new_any ());
8665 assert (TREE_CODE (DECL_SIZE_UNIT (eqt
)) == INTEGER_CST
);
8666 assert (0 == compare_tree_int (DECL_SIZE_UNIT (eqt
),
8667 (ffestorag_size (eqst
)
8668 + ffestorag_modulo (eqst
))));
8671 ffestorag_set_hook (eqst
, eqt
);
8673 ffestorag_drive (ffestorag_list_equivs (eqst
),
8674 &ffecom_member_phase2_
,
8678 /* Implement NAMELIST in back end. See f2c/format.c for more info. */
8681 ffecom_transform_namelist_ (ffesymbol s
)
8684 tree nmltype
= ffecom_type_namelist_ ();
8692 static int mynumber
= 0;
8694 nmlt
= build_decl (VAR_DECL
,
8695 ffecom_get_invented_identifier ("__g77_namelist_%d",
8698 TREE_STATIC (nmlt
) = 1;
8699 DECL_INITIAL (nmlt
) = error_mark_node
;
8701 nmlt
= start_decl (nmlt
, FALSE
);
8703 /* Process inits. */
8705 i
= strlen (ffesymbol_text (s
));
8707 high
= build_int_2 (i
, 0);
8708 TREE_TYPE (high
) = ffecom_f2c_ftnlen_type_node
;
8710 nameinit
= ffecom_build_f2c_string_ (i
+ 1,
8711 ffesymbol_text (s
));
8712 TREE_TYPE (nameinit
)
8713 = build_type_variant
8716 build_range_type (ffecom_f2c_ftnlen_type_node
,
8717 ffecom_f2c_ftnlen_one_node
,
8720 TREE_CONSTANT (nameinit
) = 1;
8721 TREE_STATIC (nameinit
) = 1;
8722 nameinit
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (nameinit
)),
8725 varsinit
= ffecom_vardesc_array_ (s
);
8726 varsinit
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (varsinit
)),
8728 TREE_CONSTANT (varsinit
) = 1;
8729 TREE_STATIC (varsinit
) = 1;
8734 for (i
= 0, b
= ffesymbol_namelist (s
); b
!= NULL
; b
= ffebld_trail (b
))
8737 nvarsinit
= build_int_2 (i
, 0);
8738 TREE_TYPE (nvarsinit
) = integer_type_node
;
8739 TREE_CONSTANT (nvarsinit
) = 1;
8740 TREE_STATIC (nvarsinit
) = 1;
8742 nmlinits
= build_tree_list ((field
= TYPE_FIELDS (nmltype
)), nameinit
);
8743 TREE_CHAIN (nmlinits
) = build_tree_list ((field
= TREE_CHAIN (field
)),
8745 TREE_CHAIN (TREE_CHAIN (nmlinits
))
8746 = build_tree_list ((field
= TREE_CHAIN (field
)), nvarsinit
);
8748 nmlinits
= build_constructor (nmltype
, nmlinits
);
8749 TREE_CONSTANT (nmlinits
) = 1;
8750 TREE_STATIC (nmlinits
) = 1;
8752 finish_decl (nmlt
, nmlinits
, FALSE
);
8754 nmlt
= ffecom_1 (ADDR_EXPR
, build_pointer_type (nmltype
), nmlt
);
8759 /* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
8760 analyzed on the assumption it is calculating a pointer to be
8761 indirected through. It must return the proper decl and offset,
8762 taking into account different units of measurements for offsets. */
8765 ffecom_tree_canonize_ptr_ (tree
*decl
, tree
*offset
, tree t
)
8767 switch (TREE_CODE (t
))
8771 case NON_LVALUE_EXPR
:
8772 ffecom_tree_canonize_ptr_ (decl
, offset
, TREE_OPERAND (t
, 0));
8776 ffecom_tree_canonize_ptr_ (decl
, offset
, TREE_OPERAND (t
, 0));
8777 if ((*decl
== NULL_TREE
)
8778 || (*decl
== error_mark_node
))
8781 if (TREE_CODE (TREE_OPERAND (t
, 1)) == INTEGER_CST
)
8783 /* An offset into COMMON. */
8784 *offset
= fold (build (PLUS_EXPR
, TREE_TYPE (*offset
),
8785 *offset
, TREE_OPERAND (t
, 1)));
8786 /* Convert offset (presumably in bytes) into canonical units
8787 (presumably bits). */
8788 *offset
= size_binop (MULT_EXPR
,
8789 convert (bitsizetype
, *offset
),
8790 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t
))));
8793 /* Not a COMMON reference, so an unrecognized pattern. */
8794 *decl
= error_mark_node
;
8799 *offset
= bitsize_zero_node
;
8803 if (TREE_CODE (TREE_OPERAND (t
, 0)) == VAR_DECL
)
8805 /* A reference to COMMON. */
8806 *decl
= TREE_OPERAND (t
, 0);
8807 *offset
= bitsize_zero_node
;
8812 /* Not a COMMON reference, so an unrecognized pattern. */
8813 *decl
= error_mark_node
;
8818 /* Given a tree that is possibly intended for use as an lvalue, return
8819 information representing a canonical view of that tree as a decl, an
8820 offset into that decl, and a size for the lvalue.
8822 If there's no applicable decl, NULL_TREE is returned for the decl,
8823 and the other fields are left undefined.
8825 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
8826 is returned for the decl, and the other fields are left undefined.
8828 Otherwise, the decl returned currently is either a VAR_DECL or a
8831 The offset returned is always valid, but of course not necessarily
8832 a constant, and not necessarily converted into the appropriate
8833 type, leaving that up to the caller (so as to avoid that overhead
8834 if the decls being looked at are different anyway).
8836 If the size cannot be determined (e.g. an adjustable array),
8837 an ERROR_MARK node is returned for the size. Otherwise, the
8838 size returned is valid, not necessarily a constant, and not
8839 necessarily converted into the appropriate type as with the
8842 Note that the offset and size expressions are expressed in the
8843 base storage units (usually bits) rather than in the units of
8844 the type of the decl, because two decls with different types
8845 might overlap but with apparently non-overlapping array offsets,
8846 whereas converting the array offsets to consistant offsets will
8847 reveal the overlap. */
8850 ffecom_tree_canonize_ref_ (tree
*decl
, tree
*offset
, tree
*size
, tree t
)
8852 /* The default path is to report a nonexistant decl. */
8858 switch (TREE_CODE (t
))
8861 case IDENTIFIER_NODE
:
8870 case TRUNC_DIV_EXPR
:
8872 case FLOOR_DIV_EXPR
:
8873 case ROUND_DIV_EXPR
:
8874 case TRUNC_MOD_EXPR
:
8876 case FLOOR_MOD_EXPR
:
8877 case ROUND_MOD_EXPR
:
8879 case EXACT_DIV_EXPR
:
8880 case FIX_TRUNC_EXPR
:
8882 case FIX_FLOOR_EXPR
:
8883 case FIX_ROUND_EXPR
:
8897 case TRUTH_ANDIF_EXPR
:
8898 case TRUTH_ORIF_EXPR
:
8899 case TRUTH_AND_EXPR
:
8901 case TRUTH_XOR_EXPR
:
8902 case TRUTH_NOT_EXPR
:
8922 *offset
= bitsize_zero_node
;
8923 *size
= TYPE_SIZE (TREE_TYPE (t
));
8928 tree array
= TREE_OPERAND (t
, 0);
8929 tree element
= TREE_OPERAND (t
, 1);
8932 if ((array
== NULL_TREE
)
8933 || (element
== NULL_TREE
))
8935 *decl
= error_mark_node
;
8939 ffecom_tree_canonize_ref_ (decl
, &init_offset
, size
,
8941 if ((*decl
== NULL_TREE
)
8942 || (*decl
== error_mark_node
))
8945 /* Calculate ((element - base) * NBBY) + init_offset. */
8946 *offset
= fold (build (MINUS_EXPR
, TREE_TYPE (element
),
8948 TYPE_MIN_VALUE (TYPE_DOMAIN
8949 (TREE_TYPE (array
)))));
8951 *offset
= size_binop (MULT_EXPR
,
8952 convert (bitsizetype
, *offset
),
8953 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array
))));
8955 *offset
= size_binop (PLUS_EXPR
, init_offset
, *offset
);
8957 *size
= TYPE_SIZE (TREE_TYPE (t
));
8963 /* Most of this code is to handle references to COMMON. And so
8964 far that is useful only for calling library functions, since
8965 external (user) functions might reference common areas. But
8966 even calling an external function, it's worthwhile to decode
8967 COMMON references because if not storing into COMMON, we don't
8968 want COMMON-based arguments to gratuitously force use of a
8971 *size
= TYPE_SIZE (TREE_TYPE (t
));
8973 ffecom_tree_canonize_ptr_ (decl
, offset
,
8974 TREE_OPERAND (t
, 0));
8981 case NON_LVALUE_EXPR
:
8984 case COND_EXPR
: /* More cases than we can handle. */
8986 case REFERENCE_EXPR
:
8987 case PREDECREMENT_EXPR
:
8988 case PREINCREMENT_EXPR
:
8989 case POSTDECREMENT_EXPR
:
8990 case POSTINCREMENT_EXPR
:
8993 *decl
= error_mark_node
;
8998 /* Do divide operation appropriate to type of operands. */
9001 ffecom_tree_divide_ (tree tree_type
, tree left
, tree right
, tree dest_tree
,
9002 ffebld dest
, bool *dest_used
, tree hook
)
9004 if ((left
== error_mark_node
)
9005 || (right
== error_mark_node
))
9006 return error_mark_node
;
9008 switch (TREE_CODE (tree_type
))
9011 return ffecom_2 (TRUNC_DIV_EXPR
, tree_type
,
9016 if (! optimize_size
)
9017 return ffecom_2 (RDIV_EXPR
, tree_type
,
9023 if (TREE_TYPE (tree_type
)
9024 == ffecom_tree_type
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL1
])
9025 ix
= FFECOM_gfrtDIV_CC
; /* Overlapping result okay. */
9027 ix
= FFECOM_gfrtDIV_ZZ
; /* Overlapping result okay. */
9029 left
= ffecom_1 (ADDR_EXPR
,
9030 build_pointer_type (TREE_TYPE (left
)),
9032 left
= build_tree_list (NULL_TREE
, left
);
9033 right
= ffecom_1 (ADDR_EXPR
,
9034 build_pointer_type (TREE_TYPE (right
)),
9036 right
= build_tree_list (NULL_TREE
, right
);
9037 TREE_CHAIN (left
) = right
;
9039 return ffecom_call_ (ffecom_gfrt_tree_ (ix
),
9040 ffecom_gfrt_kindtype (ix
),
9041 ffe_is_f2c_library (),
9044 dest_tree
, dest
, dest_used
,
9045 NULL_TREE
, TRUE
, hook
);
9053 if (TREE_TYPE (TYPE_FIELDS (tree_type
))
9054 == ffecom_tree_type
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL1
])
9055 ix
= FFECOM_gfrtDIV_CC
; /* Overlapping result okay. */
9057 ix
= FFECOM_gfrtDIV_ZZ
; /* Overlapping result okay. */
9059 left
= ffecom_1 (ADDR_EXPR
,
9060 build_pointer_type (TREE_TYPE (left
)),
9062 left
= build_tree_list (NULL_TREE
, left
);
9063 right
= ffecom_1 (ADDR_EXPR
,
9064 build_pointer_type (TREE_TYPE (right
)),
9066 right
= build_tree_list (NULL_TREE
, right
);
9067 TREE_CHAIN (left
) = right
;
9069 return ffecom_call_ (ffecom_gfrt_tree_ (ix
),
9070 ffecom_gfrt_kindtype (ix
),
9071 ffe_is_f2c_library (),
9074 dest_tree
, dest
, dest_used
,
9075 NULL_TREE
, TRUE
, hook
);
9080 return ffecom_2 (RDIV_EXPR
, tree_type
,
9086 /* Build type info for non-dummy variable. */
9089 ffecom_type_localvar_ (ffesymbol s
, ffeinfoBasictype bt
, ffeinfoKindtype kt
)
9097 type
= ffecom_tree_type
[bt
][kt
];
9098 if (bt
== FFEINFO_basictypeCHARACTER
)
9100 hight
= build_int_2 (ffesymbol_size (s
), 0);
9101 TREE_TYPE (hight
) = ffecom_f2c_ftnlen_type_node
;
9106 build_range_type (ffecom_f2c_ftnlen_type_node
,
9107 ffecom_f2c_ftnlen_one_node
,
9109 type
= ffecom_check_size_overflow_ (s
, type
, FALSE
);
9112 for (dl
= ffesymbol_dims (s
); dl
!= NULL
; dl
= ffebld_trail (dl
))
9114 if (type
== error_mark_node
)
9117 dim
= ffebld_head (dl
);
9118 assert (ffebld_op (dim
) == FFEBLD_opBOUNDS
);
9120 if (ffebld_left (dim
) == NULL
)
9121 lowt
= integer_one_node
;
9123 lowt
= ffecom_expr (ffebld_left (dim
));
9125 if (TREE_CODE (lowt
) != INTEGER_CST
)
9126 lowt
= variable_size (lowt
);
9128 assert (ffebld_right (dim
) != NULL
);
9129 hight
= ffecom_expr (ffebld_right (dim
));
9131 if (TREE_CODE (hight
) != INTEGER_CST
)
9132 hight
= variable_size (hight
);
9134 type
= build_array_type (type
,
9135 build_range_type (ffecom_integer_type_node
,
9137 type
= ffecom_check_size_overflow_ (s
, type
, FALSE
);
9143 /* Build Namelist type. */
9145 static GTY(()) tree ffecom_type_namelist_var
;
9147 ffecom_type_namelist_ (void)
9149 if (ffecom_type_namelist_var
== NULL_TREE
)
9151 tree namefield
, varsfield
, nvarsfield
, vardesctype
, type
;
9153 vardesctype
= ffecom_type_vardesc_ ();
9155 type
= make_node (RECORD_TYPE
);
9157 vardesctype
= build_pointer_type (build_pointer_type (vardesctype
));
9159 namefield
= ffecom_decl_field (type
, NULL_TREE
, "name",
9161 varsfield
= ffecom_decl_field (type
, namefield
, "vars", vardesctype
);
9162 nvarsfield
= ffecom_decl_field (type
, varsfield
, "nvars",
9165 TYPE_FIELDS (type
) = namefield
;
9168 ffecom_type_namelist_var
= type
;
9171 return ffecom_type_namelist_var
;
9174 /* Build Vardesc type. */
9176 static GTY(()) tree ffecom_type_vardesc_var
;
9178 ffecom_type_vardesc_ (void)
9180 if (ffecom_type_vardesc_var
== NULL_TREE
)
9182 tree namefield
, addrfield
, dimsfield
, typefield
, type
;
9183 type
= make_node (RECORD_TYPE
);
9185 namefield
= ffecom_decl_field (type
, NULL_TREE
, "name",
9187 addrfield
= ffecom_decl_field (type
, namefield
, "addr",
9189 dimsfield
= ffecom_decl_field (type
, addrfield
, "dims",
9190 ffecom_f2c_ptr_to_ftnlen_type_node
);
9191 typefield
= ffecom_decl_field (type
, dimsfield
, "type",
9194 TYPE_FIELDS (type
) = namefield
;
9197 ffecom_type_vardesc_var
= type
;
9200 return ffecom_type_vardesc_var
;
9204 ffecom_vardesc_ (ffebld expr
)
9208 assert (ffebld_op (expr
) == FFEBLD_opSYMTER
);
9209 s
= ffebld_symter (expr
);
9211 if (ffesymbol_hook (s
).vardesc_tree
== NULL_TREE
)
9214 tree vardesctype
= ffecom_type_vardesc_ ();
9222 static int mynumber
= 0;
9224 var
= build_decl (VAR_DECL
,
9225 ffecom_get_invented_identifier ("__g77_vardesc_%d",
9228 TREE_STATIC (var
) = 1;
9229 DECL_INITIAL (var
) = error_mark_node
;
9231 var
= start_decl (var
, FALSE
);
9233 /* Process inits. */
9235 nameinit
= ffecom_build_f2c_string_ ((i
= strlen (ffesymbol_text (s
)))
9237 ffesymbol_text (s
));
9238 TREE_TYPE (nameinit
)
9239 = build_type_variant
9242 build_range_type (integer_type_node
,
9244 build_int_2 (i
, 0))),
9246 TREE_CONSTANT (nameinit
) = 1;
9247 TREE_STATIC (nameinit
) = 1;
9248 nameinit
= ffecom_1 (ADDR_EXPR
,
9249 build_pointer_type (TREE_TYPE (nameinit
)),
9252 addrinit
= ffecom_arg_ptr_to_expr (expr
, &typeinit
);
9254 dimsinit
= ffecom_vardesc_dims_ (s
);
9256 if (typeinit
== NULL_TREE
)
9258 ffeinfoBasictype bt
= ffesymbol_basictype (s
);
9259 ffeinfoKindtype kt
= ffesymbol_kindtype (s
);
9260 int tc
= ffecom_f2c_typecode (bt
, kt
);
9263 typeinit
= build_int_2 (tc
, (tc
< 0) ? -1 : 0);
9266 typeinit
= ffecom_1 (NEGATE_EXPR
, TREE_TYPE (typeinit
), typeinit
);
9268 varinits
= build_tree_list ((field
= TYPE_FIELDS (vardesctype
)),
9270 TREE_CHAIN (varinits
) = build_tree_list ((field
= TREE_CHAIN (field
)),
9272 TREE_CHAIN (TREE_CHAIN (varinits
))
9273 = build_tree_list ((field
= TREE_CHAIN (field
)), dimsinit
);
9274 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits
)))
9275 = build_tree_list ((field
= TREE_CHAIN (field
)), typeinit
);
9277 varinits
= build_constructor (vardesctype
, varinits
);
9278 TREE_CONSTANT (varinits
) = 1;
9279 TREE_STATIC (varinits
) = 1;
9281 finish_decl (var
, varinits
, FALSE
);
9283 var
= ffecom_1 (ADDR_EXPR
, build_pointer_type (vardesctype
), var
);
9285 ffesymbol_hook (s
).vardesc_tree
= var
;
9288 return ffesymbol_hook (s
).vardesc_tree
;
9292 ffecom_vardesc_array_ (ffesymbol s
)
9296 tree item
= NULL_TREE
;
9299 static int mynumber
= 0;
9301 for (i
= 0, list
= NULL_TREE
, b
= ffesymbol_namelist (s
);
9303 b
= ffebld_trail (b
), ++i
)
9307 t
= ffecom_vardesc_ (ffebld_head (b
));
9309 if (list
== NULL_TREE
)
9310 list
= item
= build_tree_list (NULL_TREE
, t
);
9313 TREE_CHAIN (item
) = build_tree_list (NULL_TREE
, t
);
9314 item
= TREE_CHAIN (item
);
9318 item
= build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9319 build_range_type (integer_type_node
,
9321 build_int_2 (i
, 0)));
9322 list
= build_constructor (item
, list
);
9323 TREE_CONSTANT (list
) = 1;
9324 TREE_STATIC (list
) = 1;
9326 var
= ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber
++);
9327 var
= build_decl (VAR_DECL
, var
, item
);
9328 TREE_STATIC (var
) = 1;
9329 DECL_INITIAL (var
) = error_mark_node
;
9330 var
= start_decl (var
, FALSE
);
9331 finish_decl (var
, list
, FALSE
);
9337 ffecom_vardesc_dims_ (ffesymbol s
)
9339 if (ffesymbol_dims (s
) == NULL
)
9340 return convert (ffecom_f2c_ptr_to_ftnlen_type_node
,
9348 tree item
= NULL_TREE
;
9352 tree baseoff
= NULL_TREE
;
9353 static int mynumber
= 0;
9355 numdim
= build_int_2 ((int) ffesymbol_rank (s
), 0);
9356 TREE_TYPE (numdim
) = ffecom_f2c_ftnlen_type_node
;
9358 numelem
= ffecom_expr (ffesymbol_arraysize (s
));
9359 TREE_TYPE (numelem
) = ffecom_f2c_ftnlen_type_node
;
9362 backlist
= NULL_TREE
;
9363 for (b
= ffesymbol_dims (s
), e
= ffesymbol_extents (s
);
9365 b
= ffebld_trail (b
), e
= ffebld_trail (e
))
9371 if (ffebld_trail (b
) == NULL
)
9375 t
= convert (ffecom_f2c_ftnlen_type_node
,
9376 ffecom_expr (ffebld_head (e
)));
9378 if (list
== NULL_TREE
)
9379 list
= item
= build_tree_list (NULL_TREE
, t
);
9382 TREE_CHAIN (item
) = build_tree_list (NULL_TREE
, t
);
9383 item
= TREE_CHAIN (item
);
9387 if (ffebld_left (ffebld_head (b
)) == NULL
)
9388 low
= ffecom_integer_one_node
;
9390 low
= ffecom_expr (ffebld_left (ffebld_head (b
)));
9391 low
= convert (ffecom_f2c_ftnlen_type_node
, low
);
9393 back
= build_tree_list (low
, t
);
9394 TREE_CHAIN (back
) = backlist
;
9398 for (item
= backlist
; item
!= NULL_TREE
; item
= TREE_CHAIN (item
))
9400 if (TREE_VALUE (item
) == NULL_TREE
)
9401 baseoff
= TREE_PURPOSE (item
);
9403 baseoff
= ffecom_2 (PLUS_EXPR
, ffecom_f2c_ftnlen_type_node
,
9404 TREE_PURPOSE (item
),
9405 ffecom_2 (MULT_EXPR
,
9406 ffecom_f2c_ftnlen_type_node
,
9411 /* backlist now dead, along with all TREE_PURPOSEs on it. */
9413 baseoff
= build_tree_list (NULL_TREE
, baseoff
);
9414 TREE_CHAIN (baseoff
) = list
;
9416 numelem
= build_tree_list (NULL_TREE
, numelem
);
9417 TREE_CHAIN (numelem
) = baseoff
;
9419 numdim
= build_tree_list (NULL_TREE
, numdim
);
9420 TREE_CHAIN (numdim
) = numelem
;
9422 item
= build_array_type (ffecom_f2c_ftnlen_type_node
,
9423 build_range_type (integer_type_node
,
9426 ((int) ffesymbol_rank (s
)
9428 list
= build_constructor (item
, numdim
);
9429 TREE_CONSTANT (list
) = 1;
9430 TREE_STATIC (list
) = 1;
9432 var
= ffecom_get_invented_identifier ("__g77_dims_%d", mynumber
++);
9433 var
= build_decl (VAR_DECL
, var
, item
);
9434 TREE_STATIC (var
) = 1;
9435 DECL_INITIAL (var
) = error_mark_node
;
9436 var
= start_decl (var
, FALSE
);
9437 finish_decl (var
, list
, FALSE
);
9439 var
= ffecom_1 (ADDR_EXPR
, build_pointer_type (item
), var
);
9445 /* Essentially does a "fold (build1 (code, type, node))" while checking
9446 for certain housekeeping things.
9448 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9449 ffecom_1_fn instead. */
9452 ffecom_1 (enum tree_code code
, tree type
, tree node
)
9456 if ((node
== error_mark_node
)
9457 || (type
== error_mark_node
))
9458 return error_mark_node
;
9460 if (code
== ADDR_EXPR
)
9462 if (!ffe_mark_addressable (node
))
9463 assert ("can't mark_addressable this node!" == NULL
);
9466 switch (ffe_is_emulate_complex () ? code
: NOP_EXPR
)
9471 item
= build (COMPONENT_REF
, type
, node
, TYPE_FIELDS (TREE_TYPE (node
)));
9475 item
= build (COMPONENT_REF
, type
, node
, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node
))));
9480 if (TREE_CODE (type
) != RECORD_TYPE
)
9482 item
= build1 (code
, type
, node
);
9485 node
= ffecom_stabilize_aggregate_ (node
);
9486 realtype
= TREE_TYPE (TYPE_FIELDS (type
));
9488 ffecom_2 (COMPLEX_EXPR
, type
,
9489 ffecom_1 (NEGATE_EXPR
, realtype
,
9490 ffecom_1 (REALPART_EXPR
, realtype
,
9492 ffecom_1 (NEGATE_EXPR
, realtype
,
9493 ffecom_1 (IMAGPART_EXPR
, realtype
,
9498 item
= build1 (code
, type
, node
);
9502 if (TREE_SIDE_EFFECTS (node
))
9503 TREE_SIDE_EFFECTS (item
) = 1;
9504 if (code
== ADDR_EXPR
&& staticp (node
))
9505 TREE_CONSTANT (item
) = 1;
9506 else if (code
== INDIRECT_REF
)
9507 TREE_READONLY (item
) = TYPE_READONLY (type
);
9511 /* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9512 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9513 does not set TREE_ADDRESSABLE (because calling an inline
9514 function does not mean the function needs to be separately
9518 ffecom_1_fn (tree node
)
9523 if (node
== error_mark_node
)
9524 return error_mark_node
;
9526 type
= build_type_variant (TREE_TYPE (node
),
9527 TREE_READONLY (node
),
9528 TREE_THIS_VOLATILE (node
));
9529 item
= build1 (ADDR_EXPR
,
9530 build_pointer_type (type
), node
);
9531 if (TREE_SIDE_EFFECTS (node
))
9532 TREE_SIDE_EFFECTS (item
) = 1;
9534 TREE_CONSTANT (item
) = 1;
9538 /* Essentially does a "fold (build (code, type, node1, node2))" while
9539 checking for certain housekeeping things. */
9542 ffecom_2 (enum tree_code code
, tree type
, tree node1
, tree node2
)
9546 if ((node1
== error_mark_node
)
9547 || (node2
== error_mark_node
)
9548 || (type
== error_mark_node
))
9549 return error_mark_node
;
9551 switch (ffe_is_emulate_complex () ? code
: NOP_EXPR
)
9553 tree a
, b
, c
, d
, realtype
;
9556 assert ("no CONJ_EXPR support yet" == NULL
);
9557 return error_mark_node
;
9560 item
= build_tree_list (TYPE_FIELDS (type
), node1
);
9561 TREE_CHAIN (item
) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type
)), node2
);
9562 item
= build_constructor (type
, item
);
9566 if (TREE_CODE (type
) != RECORD_TYPE
)
9568 item
= build (code
, type
, node1
, node2
);
9571 node1
= ffecom_stabilize_aggregate_ (node1
);
9572 node2
= ffecom_stabilize_aggregate_ (node2
);
9573 realtype
= TREE_TYPE (TYPE_FIELDS (type
));
9575 ffecom_2 (COMPLEX_EXPR
, type
,
9576 ffecom_2 (PLUS_EXPR
, realtype
,
9577 ffecom_1 (REALPART_EXPR
, realtype
,
9579 ffecom_1 (REALPART_EXPR
, realtype
,
9581 ffecom_2 (PLUS_EXPR
, realtype
,
9582 ffecom_1 (IMAGPART_EXPR
, realtype
,
9584 ffecom_1 (IMAGPART_EXPR
, realtype
,
9589 if (TREE_CODE (type
) != RECORD_TYPE
)
9591 item
= build (code
, type
, node1
, node2
);
9594 node1
= ffecom_stabilize_aggregate_ (node1
);
9595 node2
= ffecom_stabilize_aggregate_ (node2
);
9596 realtype
= TREE_TYPE (TYPE_FIELDS (type
));
9598 ffecom_2 (COMPLEX_EXPR
, type
,
9599 ffecom_2 (MINUS_EXPR
, realtype
,
9600 ffecom_1 (REALPART_EXPR
, realtype
,
9602 ffecom_1 (REALPART_EXPR
, realtype
,
9604 ffecom_2 (MINUS_EXPR
, realtype
,
9605 ffecom_1 (IMAGPART_EXPR
, realtype
,
9607 ffecom_1 (IMAGPART_EXPR
, realtype
,
9612 if (TREE_CODE (type
) != RECORD_TYPE
)
9614 item
= build (code
, type
, node1
, node2
);
9617 node1
= ffecom_stabilize_aggregate_ (node1
);
9618 node2
= ffecom_stabilize_aggregate_ (node2
);
9619 realtype
= TREE_TYPE (TYPE_FIELDS (type
));
9620 a
= save_expr (ffecom_1 (REALPART_EXPR
, realtype
,
9622 b
= save_expr (ffecom_1 (IMAGPART_EXPR
, realtype
,
9624 c
= save_expr (ffecom_1 (REALPART_EXPR
, realtype
,
9626 d
= save_expr (ffecom_1 (IMAGPART_EXPR
, realtype
,
9629 ffecom_2 (COMPLEX_EXPR
, type
,
9630 ffecom_2 (MINUS_EXPR
, realtype
,
9631 ffecom_2 (MULT_EXPR
, realtype
,
9634 ffecom_2 (MULT_EXPR
, realtype
,
9637 ffecom_2 (PLUS_EXPR
, realtype
,
9638 ffecom_2 (MULT_EXPR
, realtype
,
9641 ffecom_2 (MULT_EXPR
, realtype
,
9647 if ((TREE_CODE (node1
) != RECORD_TYPE
)
9648 && (TREE_CODE (node2
) != RECORD_TYPE
))
9650 item
= build (code
, type
, node1
, node2
);
9653 assert (TREE_CODE (node1
) == RECORD_TYPE
);
9654 assert (TREE_CODE (node2
) == RECORD_TYPE
);
9655 node1
= ffecom_stabilize_aggregate_ (node1
);
9656 node2
= ffecom_stabilize_aggregate_ (node2
);
9657 realtype
= TREE_TYPE (TYPE_FIELDS (type
));
9659 ffecom_2 (TRUTH_ANDIF_EXPR
, type
,
9660 ffecom_2 (code
, type
,
9661 ffecom_1 (REALPART_EXPR
, realtype
,
9663 ffecom_1 (REALPART_EXPR
, realtype
,
9665 ffecom_2 (code
, type
,
9666 ffecom_1 (IMAGPART_EXPR
, realtype
,
9668 ffecom_1 (IMAGPART_EXPR
, realtype
,
9673 if ((TREE_CODE (node1
) != RECORD_TYPE
)
9674 && (TREE_CODE (node2
) != RECORD_TYPE
))
9676 item
= build (code
, type
, node1
, node2
);
9679 assert (TREE_CODE (node1
) == RECORD_TYPE
);
9680 assert (TREE_CODE (node2
) == RECORD_TYPE
);
9681 node1
= ffecom_stabilize_aggregate_ (node1
);
9682 node2
= ffecom_stabilize_aggregate_ (node2
);
9683 realtype
= TREE_TYPE (TYPE_FIELDS (type
));
9685 ffecom_2 (TRUTH_ORIF_EXPR
, type
,
9686 ffecom_2 (code
, type
,
9687 ffecom_1 (REALPART_EXPR
, realtype
,
9689 ffecom_1 (REALPART_EXPR
, realtype
,
9691 ffecom_2 (code
, type
,
9692 ffecom_1 (IMAGPART_EXPR
, realtype
,
9694 ffecom_1 (IMAGPART_EXPR
, realtype
,
9699 item
= build (code
, type
, node1
, node2
);
9703 if (TREE_SIDE_EFFECTS (node1
) || TREE_SIDE_EFFECTS (node2
))
9704 TREE_SIDE_EFFECTS (item
) = 1;
9708 /* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
9710 ffesymbol s; // the ENTRY point itself
9711 if (ffecom_2pass_advise_entrypoint(s))
9712 // the ENTRY point has been accepted
9714 Does whatever compiler needs to do when it learns about the entrypoint,
9715 like determine the return type of the master function, count the
9716 number of entrypoints, etc. Returns FALSE if the return type is
9717 not compatible with the return type(s) of other entrypoint(s).
9719 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
9720 later (after _finish_progunit) be called with the same entrypoint(s)
9721 as passed to this fn for which TRUE was returned.
9724 Return FALSE if the return type conflicts with previous entrypoints. */
9727 ffecom_2pass_advise_entrypoint (ffesymbol entry
)
9729 ffebld list
; /* opITEM. */
9730 ffebld mlist
; /* opITEM. */
9731 ffebld plist
; /* opITEM. */
9732 ffebld arg
; /* ffebld_head(opITEM). */
9733 ffebld item
; /* opITEM. */
9734 ffesymbol s
; /* ffebld_symter(arg). */
9735 ffeinfoBasictype bt
= ffesymbol_basictype (entry
);
9736 ffeinfoKindtype kt
= ffesymbol_kindtype (entry
);
9737 ffetargetCharacterSize size
= ffesymbol_size (entry
);
9740 if (ffecom_num_entrypoints_
== 0)
9741 { /* First entrypoint, make list of main
9742 arglist's dummies. */
9743 assert (ffecom_primary_entry_
!= NULL
);
9745 ffecom_master_bt_
= ffesymbol_basictype (ffecom_primary_entry_
);
9746 ffecom_master_kt_
= ffesymbol_kindtype (ffecom_primary_entry_
);
9747 ffecom_master_size_
= ffesymbol_size (ffecom_primary_entry_
);
9749 for (plist
= NULL
, list
= ffesymbol_dummyargs (ffecom_primary_entry_
);
9751 list
= ffebld_trail (list
))
9753 arg
= ffebld_head (list
);
9754 if (ffebld_op (arg
) != FFEBLD_opSYMTER
)
9755 continue; /* Alternate return or some such thing. */
9756 item
= ffebld_new_item (arg
, NULL
);
9758 ffecom_master_arglist_
= item
;
9760 ffebld_set_trail (plist
, item
);
9765 /* If necessary, scan entry arglist for alternate returns. Do this scan
9766 apparently redundantly (it's done below to UNIONize the arglists) so
9767 that we don't complain about RETURN 1 if an offending ENTRY is the only
9768 one with an alternate return. */
9770 if (!ffecom_is_altreturning_
)
9772 for (list
= ffesymbol_dummyargs (entry
);
9774 list
= ffebld_trail (list
))
9776 arg
= ffebld_head (list
);
9777 if (ffebld_op (arg
) == FFEBLD_opSTAR
)
9779 ffecom_is_altreturning_
= TRUE
;
9785 /* Now check type compatibility. */
9787 switch (ffecom_master_bt_
)
9789 case FFEINFO_basictypeNONE
:
9790 ok
= (bt
!= FFEINFO_basictypeCHARACTER
);
9793 case FFEINFO_basictypeCHARACTER
:
9795 = (bt
== FFEINFO_basictypeCHARACTER
)
9796 && (kt
== ffecom_master_kt_
)
9797 && (size
== ffecom_master_size_
);
9800 case FFEINFO_basictypeANY
:
9801 return FALSE
; /* Just don't bother. */
9804 if (bt
== FFEINFO_basictypeCHARACTER
)
9810 if ((bt
!= ffecom_master_bt_
) || (kt
!= ffecom_master_kt_
))
9812 ffecom_master_bt_
= FFEINFO_basictypeNONE
;
9813 ffecom_master_kt_
= FFEINFO_kindtypeNONE
;
9820 ffebad_start (FFEBAD_ENTRY_CONFLICTS
);
9821 ffest_ffebad_here_current_stmt (0);
9823 return FALSE
; /* Can't handle entrypoint. */
9826 /* Entrypoint type compatible with previous types. */
9828 ++ffecom_num_entrypoints_
;
9830 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
9832 for (list
= ffesymbol_dummyargs (entry
);
9834 list
= ffebld_trail (list
))
9836 arg
= ffebld_head (list
);
9837 if (ffebld_op (arg
) != FFEBLD_opSYMTER
)
9838 continue; /* Alternate return or some such thing. */
9839 s
= ffebld_symter (arg
);
9840 for (plist
= NULL
, mlist
= ffecom_master_arglist_
;
9842 plist
= mlist
, mlist
= ffebld_trail (mlist
))
9843 { /* plist points to previous item for easy
9844 appending of arg. */
9845 if (ffebld_symter (ffebld_head (mlist
)) == s
)
9846 break; /* Already have this arg in the master list. */
9849 continue; /* Already have this arg in the master list. */
9851 /* Append this arg to the master list. */
9853 item
= ffebld_new_item (arg
, NULL
);
9855 ffecom_master_arglist_
= item
;
9857 ffebld_set_trail (plist
, item
);
9863 /* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
9865 ffesymbol s; // the ENTRY point itself
9866 ffecom_2pass_do_entrypoint(s);
9868 Does whatever compiler needs to do to make the entrypoint actually
9869 happen. Must be called for each entrypoint after
9870 ffecom_finish_progunit is called. */
9873 ffecom_2pass_do_entrypoint (ffesymbol entry
)
9875 static int mfn_num
= 0;
9878 if (mfn_num
!= ffecom_num_fns_
)
9879 { /* First entrypoint for this program unit. */
9881 mfn_num
= ffecom_num_fns_
;
9882 ffecom_do_entry_ (ffecom_primary_entry_
, 0);
9887 --ffecom_num_entrypoints_
;
9889 ffecom_do_entry_ (entry
, ent_num
);
9892 /* Essentially does a "fold (build (code, type, node1, node2))" while
9893 checking for certain housekeeping things. Always sets
9894 TREE_SIDE_EFFECTS. */
9897 ffecom_2s (enum tree_code code
, tree type
, tree node1
, tree node2
)
9901 if ((node1
== error_mark_node
)
9902 || (node2
== error_mark_node
)
9903 || (type
== error_mark_node
))
9904 return error_mark_node
;
9906 item
= build (code
, type
, node1
, node2
);
9907 TREE_SIDE_EFFECTS (item
) = 1;
9911 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
9912 checking for certain housekeeping things. */
9915 ffecom_3 (enum tree_code code
, tree type
, tree node1
, tree node2
, tree node3
)
9919 if ((node1
== error_mark_node
)
9920 || (node2
== error_mark_node
)
9921 || (node3
== error_mark_node
)
9922 || (type
== error_mark_node
))
9923 return error_mark_node
;
9925 item
= build (code
, type
, node1
, node2
, node3
);
9926 if (TREE_SIDE_EFFECTS (node1
) || TREE_SIDE_EFFECTS (node2
)
9927 || (node3
!= NULL_TREE
&& TREE_SIDE_EFFECTS (node3
)))
9928 TREE_SIDE_EFFECTS (item
) = 1;
9932 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
9933 checking for certain housekeeping things. Always sets
9934 TREE_SIDE_EFFECTS. */
9937 ffecom_3s (enum tree_code code
, tree type
, tree node1
, tree node2
, tree node3
)
9941 if ((node1
== error_mark_node
)
9942 || (node2
== error_mark_node
)
9943 || (node3
== error_mark_node
)
9944 || (type
== error_mark_node
))
9945 return error_mark_node
;
9947 item
= build (code
, type
, node1
, node2
, node3
);
9948 TREE_SIDE_EFFECTS (item
) = 1;
9952 /* ffecom_arg_expr -- Transform argument expr into gcc tree
9954 See use by ffecom_list_expr.
9956 If expression is NULL, returns an integer zero tree. If it is not
9957 a CHARACTER expression, returns whatever ffecom_expr
9958 returns and sets the length return value to NULL_TREE. Otherwise
9959 generates code to evaluate the character expression, returns the proper
9960 pointer to the result, but does NOT set the length return value to a tree
9961 that specifies the length of the result. (In other words, the length
9962 variable is always set to NULL_TREE, because a length is never passed.)
9965 Don't set returned length, since nobody needs it (yet; someday if
9966 we allow CHARACTER*(*) dummies to statement functions, we'll need
9970 ffecom_arg_expr (ffebld expr
, tree
*length
)
9974 *length
= NULL_TREE
;
9977 return integer_zero_node
;
9979 if (ffeinfo_basictype (ffebld_info (expr
)) != FFEINFO_basictypeCHARACTER
)
9980 return ffecom_expr (expr
);
9982 return ffecom_arg_ptr_to_expr (expr
, &ign
);
9985 /* Transform expression into constant argument-pointer-to-expression tree.
9987 If the expression can be transformed into a argument-pointer-to-expression
9988 tree that is constant, that is done, and the tree returned. Else
9989 NULL_TREE is returned.
9991 That way, a caller can attempt to provide compile-time initialization
9992 of a variable and, if that fails, *then* choose to start a new block
9993 and resort to using temporaries, as appropriate. */
9996 ffecom_arg_ptr_to_const_expr (ffebld expr
, tree
*length
)
9999 return integer_zero_node
;
10001 if (ffebld_op (expr
) == FFEBLD_opANY
)
10004 *length
= error_mark_node
;
10005 return error_mark_node
;
10008 if (ffebld_arity (expr
) == 0
10009 && (ffebld_op (expr
) != FFEBLD_opSYMTER
10010 || ffebld_where (expr
) == FFEINFO_whereCOMMON
10011 || ffebld_where (expr
) == FFEINFO_whereGLOBAL
10012 || ffebld_where (expr
) == FFEINFO_whereINTRINSIC
))
10016 t
= ffecom_arg_ptr_to_expr (expr
, length
);
10017 assert (TREE_CONSTANT (t
));
10018 assert (! length
|| TREE_CONSTANT (*length
));
10023 && ffebld_size (expr
) != FFETARGET_charactersizeNONE
)
10024 *length
= build_int_2 (ffebld_size (expr
), 0);
10026 *length
= NULL_TREE
;
10030 /* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
10032 See use by ffecom_list_ptr_to_expr.
10034 If expression is NULL, returns an integer zero tree. If it is not
10035 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10036 returns and sets the length return value to NULL_TREE. Otherwise
10037 generates code to evaluate the character expression, returns the proper
10038 pointer to the result, AND sets the length return value to a tree that
10039 specifies the length of the result.
10041 If the length argument is NULL, this is a slightly special
10042 case of building a FORMAT expression, that is, an expression that
10043 will be used at run time without regard to length. For the current
10044 implementation, which uses the libf2c library, this means it is nice
10045 to append a null byte to the end of the expression, where feasible,
10046 to make sure any diagnostic about the FORMAT string terminates at
10049 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10050 length argument. This might even be seen as a feature, if a null
10051 byte can always be appended. */
10054 ffecom_arg_ptr_to_expr (ffebld expr
, tree
*length
)
10058 ffecomConcatList_ catlist
;
10060 if (length
!= NULL
)
10061 *length
= NULL_TREE
;
10064 return integer_zero_node
;
10066 switch (ffebld_op (expr
))
10068 case FFEBLD_opPERCENT_VAL
:
10069 if (ffeinfo_basictype (ffebld_info (expr
)) != FFEINFO_basictypeCHARACTER
)
10070 return ffecom_expr (ffebld_left (expr
));
10075 temp_exp
= ffecom_arg_ptr_to_expr (ffebld_left (expr
), &temp_length
);
10076 if (temp_exp
== error_mark_node
)
10077 return error_mark_node
;
10079 return ffecom_1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (temp_exp
)),
10083 case FFEBLD_opPERCENT_REF
:
10084 if (ffeinfo_basictype (ffebld_info (expr
)) != FFEINFO_basictypeCHARACTER
)
10085 return ffecom_ptr_to_expr (ffebld_left (expr
));
10086 if (length
!= NULL
)
10088 ign_length
= NULL_TREE
;
10089 length
= &ign_length
;
10091 expr
= ffebld_left (expr
);
10094 case FFEBLD_opPERCENT_DESCR
:
10095 switch (ffeinfo_basictype (ffebld_info (expr
)))
10097 case FFEINFO_basictypeCHARACTER
:
10098 break; /* Passed by descriptor anyway. */
10101 item
= ffecom_ptr_to_expr (expr
);
10102 if (item
!= error_mark_node
)
10103 *length
= TYPE_SIZE (TREE_TYPE (TREE_TYPE (item
)));
10112 if (ffeinfo_basictype (ffebld_info (expr
)) != FFEINFO_basictypeCHARACTER
)
10113 return ffecom_ptr_to_expr (expr
);
10115 assert (ffeinfo_kindtype (ffebld_info (expr
))
10116 == FFEINFO_kindtypeCHARACTER1
);
10118 while (ffebld_op (expr
) == FFEBLD_opPAREN
)
10119 expr
= ffebld_left (expr
);
10121 catlist
= ffecom_concat_list_new_ (expr
, FFETARGET_charactersizeNONE
);
10122 switch (ffecom_concat_list_count_ (catlist
))
10124 case 0: /* Shouldn't happen, but in case it does... */
10125 if (length
!= NULL
)
10127 *length
= ffecom_f2c_ftnlen_zero_node
;
10128 TREE_TYPE (*length
) = ffecom_f2c_ftnlen_type_node
;
10130 ffecom_concat_list_kill_ (catlist
);
10131 return null_pointer_node
;
10133 case 1: /* The (fairly) easy case. */
10134 if (length
== NULL
)
10135 ffecom_char_args_with_null_ (&item
, &ign_length
,
10136 ffecom_concat_list_expr_ (catlist
, 0));
10138 ffecom_char_args_ (&item
, length
,
10139 ffecom_concat_list_expr_ (catlist
, 0));
10140 ffecom_concat_list_kill_ (catlist
);
10141 assert (item
!= NULL_TREE
);
10144 default: /* Must actually concatenate things. */
10149 int count
= ffecom_concat_list_count_ (catlist
);
10160 ffetargetCharacterSize sz
;
10162 sz
= ffecom_concat_list_maxlen_ (catlist
);
10164 assert (sz
!= FFETARGET_charactersizeNONE
);
10169 hook
= ffebld_nonter_hook (expr
);
10171 assert (TREE_CODE (hook
) == TREE_VEC
);
10172 assert (TREE_VEC_LENGTH (hook
) == 3);
10173 length_array
= lengths
= TREE_VEC_ELT (hook
, 0);
10174 item_array
= items
= TREE_VEC_ELT (hook
, 1);
10175 temporary
= TREE_VEC_ELT (hook
, 2);
10178 known_length
= ffecom_f2c_ftnlen_zero_node
;
10180 for (i
= 0; i
< count
; ++i
)
10183 && (length
== NULL
))
10184 ffecom_char_args_with_null_ (&citem
, &clength
,
10185 ffecom_concat_list_expr_ (catlist
, i
));
10187 ffecom_char_args_ (&citem
, &clength
,
10188 ffecom_concat_list_expr_ (catlist
, i
));
10189 if ((citem
== error_mark_node
)
10190 || (clength
== error_mark_node
))
10192 ffecom_concat_list_kill_ (catlist
);
10193 *length
= error_mark_node
;
10194 return error_mark_node
;
10198 = ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (items
),
10199 ffecom_modify (void_type_node
,
10200 ffecom_2 (ARRAY_REF
,
10201 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array
))),
10203 build_int_2 (i
, 0)),
10206 clength
= ffecom_save_tree (clength
);
10207 if (length
!= NULL
)
10209 = ffecom_2 (PLUS_EXPR
, ffecom_f2c_ftnlen_type_node
,
10213 = ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (lengths
),
10214 ffecom_modify (void_type_node
,
10215 ffecom_2 (ARRAY_REF
,
10216 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array
))),
10218 build_int_2 (i
, 0)),
10223 temporary
= ffecom_1 (ADDR_EXPR
,
10224 build_pointer_type (TREE_TYPE (temporary
)),
10227 item
= build_tree_list (NULL_TREE
, temporary
);
10229 = build_tree_list (NULL_TREE
,
10230 ffecom_1 (ADDR_EXPR
,
10231 build_pointer_type (TREE_TYPE (items
)),
10233 TREE_CHAIN (TREE_CHAIN (item
))
10234 = build_tree_list (NULL_TREE
,
10235 ffecom_1 (ADDR_EXPR
,
10236 build_pointer_type (TREE_TYPE (lengths
)),
10238 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item
)))
10241 ffecom_1 (ADDR_EXPR
, ffecom_f2c_ptr_to_ftnlen_type_node
,
10242 convert (ffecom_f2c_ftnlen_type_node
,
10243 build_int_2 (count
, 0))));
10244 num
= build_int_2 (sz
, 0);
10245 TREE_TYPE (num
) = ffecom_f2c_ftnlen_type_node
;
10246 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item
))))
10247 = build_tree_list (NULL_TREE
, num
);
10249 item
= ffecom_call_gfrt (FFECOM_gfrtCAT
, item
, NULL_TREE
);
10250 TREE_SIDE_EFFECTS (item
) = 1;
10251 item
= ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (temporary
),
10255 if (length
!= NULL
)
10256 *length
= known_length
;
10259 ffecom_concat_list_kill_ (catlist
);
10260 assert (item
!= NULL_TREE
);
10264 /* Generate call to run-time function.
10266 The first arg is the GNU Fortran Run-Time function index, the second
10267 arg is the list of arguments to pass to it. Returned is the expression
10268 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10269 result (which may be void). */
10272 ffecom_call_gfrt (ffecomGfrt ix
, tree args
, tree hook
)
10274 return ffecom_call_ (ffecom_gfrt_tree_ (ix
),
10275 ffecom_gfrt_kindtype (ix
),
10276 ffe_is_f2c_library () && ffecom_gfrt_complex_
[ix
],
10277 NULL_TREE
, args
, NULL_TREE
, NULL
,
10278 NULL
, NULL_TREE
, TRUE
, hook
);
10281 /* Transform constant-union to tree. */
10284 ffecom_constantunion (ffebldConstantUnion
*cu
, ffeinfoBasictype bt
,
10285 ffeinfoKindtype kt
, tree tree_type
)
10291 case FFEINFO_basictypeINTEGER
:
10293 HOST_WIDE_INT hi
, lo
;
10297 #if FFETARGET_okINTEGER1
10298 case FFEINFO_kindtypeINTEGER1
:
10299 lo
= ffebld_cu_val_integer1 (*cu
);
10300 hi
= (lo
< 0) ? -1 : 0;
10304 #if FFETARGET_okINTEGER2
10305 case FFEINFO_kindtypeINTEGER2
:
10306 lo
= ffebld_cu_val_integer2 (*cu
);
10307 hi
= (lo
< 0) ? -1 : 0;
10311 #if FFETARGET_okINTEGER3
10312 case FFEINFO_kindtypeINTEGER3
:
10313 lo
= ffebld_cu_val_integer3 (*cu
);
10314 hi
= (lo
< 0) ? -1 : 0;
10318 #if FFETARGET_okINTEGER4
10319 case FFEINFO_kindtypeINTEGER4
:
10320 #if HOST_BITS_PER_LONGLONG > HOST_BITS_PER_WIDE_INT
10322 long long int big
= ffebld_cu_val_integer4 (*cu
);
10323 hi
= (HOST_WIDE_INT
) (big
>> HOST_BITS_PER_WIDE_INT
);
10324 lo
= (HOST_WIDE_INT
) big
;
10327 lo
= ffebld_cu_val_integer4 (*cu
);
10328 hi
= (lo
< 0) ? -1 : 0;
10334 assert ("bad INTEGER constant kind type" == NULL
);
10335 /* Fall through. */
10336 case FFEINFO_kindtypeANY
:
10337 return error_mark_node
;
10339 item
= build_int_2 (lo
, hi
);
10340 TREE_TYPE (item
) = tree_type
;
10344 case FFEINFO_basictypeLOGICAL
:
10350 #if FFETARGET_okLOGICAL1
10351 case FFEINFO_kindtypeLOGICAL1
:
10352 val
= ffebld_cu_val_logical1 (*cu
);
10356 #if FFETARGET_okLOGICAL2
10357 case FFEINFO_kindtypeLOGICAL2
:
10358 val
= ffebld_cu_val_logical2 (*cu
);
10362 #if FFETARGET_okLOGICAL3
10363 case FFEINFO_kindtypeLOGICAL3
:
10364 val
= ffebld_cu_val_logical3 (*cu
);
10368 #if FFETARGET_okLOGICAL4
10369 case FFEINFO_kindtypeLOGICAL4
:
10370 val
= ffebld_cu_val_logical4 (*cu
);
10375 assert ("bad LOGICAL constant kind type" == NULL
);
10376 /* Fall through. */
10377 case FFEINFO_kindtypeANY
:
10378 return error_mark_node
;
10380 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10381 TREE_TYPE (item
) = tree_type
;
10385 case FFEINFO_basictypeREAL
:
10387 REAL_VALUE_TYPE val
;
10391 #if FFETARGET_okREAL1
10392 case FFEINFO_kindtypeREAL1
:
10393 val
= ffetarget_value_real1 (ffebld_cu_val_real1 (*cu
));
10397 #if FFETARGET_okREAL2
10398 case FFEINFO_kindtypeREAL2
:
10399 val
= ffetarget_value_real2 (ffebld_cu_val_real2 (*cu
));
10403 #if FFETARGET_okREAL3
10404 case FFEINFO_kindtypeREAL3
:
10405 val
= ffetarget_value_real3 (ffebld_cu_val_real3 (*cu
));
10410 assert ("bad REAL constant kind type" == NULL
);
10411 /* Fall through. */
10412 case FFEINFO_kindtypeANY
:
10413 return error_mark_node
;
10415 item
= build_real (tree_type
, val
);
10419 case FFEINFO_basictypeCOMPLEX
:
10421 REAL_VALUE_TYPE real
;
10422 REAL_VALUE_TYPE imag
;
10423 tree el_type
= ffecom_tree_type
[FFEINFO_basictypeREAL
][kt
];
10427 #if FFETARGET_okCOMPLEX1
10428 case FFEINFO_kindtypeREAL1
:
10429 real
= ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu
).real
);
10430 imag
= ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu
).imaginary
);
10434 #if FFETARGET_okCOMPLEX2
10435 case FFEINFO_kindtypeREAL2
:
10436 real
= ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu
).real
);
10437 imag
= ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu
).imaginary
);
10441 #if FFETARGET_okCOMPLEX3
10442 case FFEINFO_kindtypeREAL3
:
10443 real
= ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu
).real
);
10444 imag
= ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu
).imaginary
);
10449 assert ("bad REAL constant kind type" == NULL
);
10450 /* Fall through. */
10451 case FFEINFO_kindtypeANY
:
10452 return error_mark_node
;
10454 item
= ffecom_build_complex_constant_ (tree_type
,
10455 build_real (el_type
, real
),
10456 build_real (el_type
, imag
));
10460 case FFEINFO_basictypeCHARACTER
:
10461 { /* Happens only in DATA and similar contexts. */
10462 ffetargetCharacter1 val
;
10466 #if FFETARGET_okCHARACTER1
10467 case FFEINFO_kindtypeLOGICAL1
:
10468 val
= ffebld_cu_val_character1 (*cu
);
10473 assert ("bad CHARACTER constant kind type" == NULL
);
10474 /* Fall through. */
10475 case FFEINFO_kindtypeANY
:
10476 return error_mark_node
;
10478 item
= build_string (ffetarget_length_character1 (val
),
10479 ffetarget_text_character1 (val
));
10481 = build_type_variant (build_array_type (char_type_node
,
10483 (integer_type_node
,
10486 (ffetarget_length_character1
10492 case FFEINFO_basictypeHOLLERITH
:
10494 ffetargetHollerith h
;
10496 h
= ffebld_cu_val_hollerith (*cu
);
10498 /* If not at least as wide as default INTEGER, widen it. */
10499 if (h
.length
>= FLOAT_TYPE_SIZE
/ CHAR_TYPE_SIZE
)
10500 item
= build_string (h
.length
, h
.text
);
10503 char str
[FLOAT_TYPE_SIZE
/ CHAR_TYPE_SIZE
];
10505 memcpy (str
, h
.text
, h
.length
);
10506 memset (&str
[h
.length
], ' ',
10507 FLOAT_TYPE_SIZE
/ CHAR_TYPE_SIZE
10509 item
= build_string (FLOAT_TYPE_SIZE
/ CHAR_TYPE_SIZE
,
10513 = build_type_variant (build_array_type (char_type_node
,
10515 (integer_type_node
,
10523 case FFEINFO_basictypeTYPELESS
:
10525 ffetargetInteger1 ival
;
10526 ffetargetTypeless tless
;
10529 tless
= ffebld_cu_val_typeless (*cu
);
10530 error
= ffetarget_convert_integer1_typeless (&ival
, tless
);
10531 assert (error
== FFEBAD
);
10533 item
= build_int_2 ((int) ival
, 0);
10538 assert ("not yet on constant type" == NULL
);
10539 /* Fall through. */
10540 case FFEINFO_basictypeANY
:
10541 return error_mark_node
;
10544 TREE_CONSTANT (item
) = 1;
10549 /* Transform constant-union to tree, with the type known. */
10552 ffecom_constantunion_with_type (ffebldConstantUnion
*cu
, tree tree_type
,
10561 #if FFETARGET_okINTEGER1
10562 case FFEBLD_constINTEGER1
:
10563 val
= ffebld_cu_val_integer1 (*cu
);
10564 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10567 #if FFETARGET_okINTEGER2
10568 case FFEBLD_constINTEGER2
:
10569 val
= ffebld_cu_val_integer2 (*cu
);
10570 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10573 #if FFETARGET_okINTEGER3
10574 case FFEBLD_constINTEGER3
:
10575 val
= ffebld_cu_val_integer3 (*cu
);
10576 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10579 #if FFETARGET_okINTEGER4
10580 case FFEBLD_constINTEGER4
:
10581 #if HOST_BITS_PER_LONGLONG > HOST_BITS_PER_WIDE_INT
10583 long long int big
= ffebld_cu_val_integer4 (*cu
);
10584 item
= build_int_2 ((HOST_WIDE_INT
) big
,
10586 (big
>> HOST_BITS_PER_WIDE_INT
));
10589 val
= ffebld_cu_val_integer4 (*cu
);
10590 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10594 #if FFETARGET_okLOGICAL1
10595 case FFEBLD_constLOGICAL1
:
10596 val
= ffebld_cu_val_logical1 (*cu
);
10597 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10600 #if FFETARGET_okLOGICAL2
10601 case FFEBLD_constLOGICAL2
:
10602 val
= ffebld_cu_val_logical2 (*cu
);
10603 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10606 #if FFETARGET_okLOGICAL3
10607 case FFEBLD_constLOGICAL3
:
10608 val
= ffebld_cu_val_logical3 (*cu
);
10609 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10612 #if FFETARGET_okLOGICAL4
10613 case FFEBLD_constLOGICAL4
:
10614 val
= ffebld_cu_val_logical4 (*cu
);
10615 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10619 assert ("constant type not supported"==NULL
);
10620 return error_mark_node
;
10624 TREE_TYPE (item
) = tree_type
;
10626 TREE_CONSTANT (item
) = 1;
10630 /* Transform expression into constant tree.
10632 If the expression can be transformed into a tree that is constant,
10633 that is done, and the tree returned. Else NULL_TREE is returned.
10635 That way, a caller can attempt to provide compile-time initialization
10636 of a variable and, if that fails, *then* choose to start a new block
10637 and resort to using temporaries, as appropriate. */
10640 ffecom_const_expr (ffebld expr
)
10643 return integer_zero_node
;
10645 if (ffebld_op (expr
) == FFEBLD_opANY
)
10646 return error_mark_node
;
10648 if (ffebld_arity (expr
) == 0
10649 && (ffebld_op (expr
) != FFEBLD_opSYMTER
10650 || ffebld_where (expr
) == FFEINFO_whereGLOBAL
10651 || ffebld_where (expr
) == FFEINFO_whereINTRINSIC
))
10655 t
= ffecom_expr (expr
);
10656 assert (TREE_CONSTANT (t
));
10663 /* Handy way to make a field in a struct/union. */
10666 ffecom_decl_field (tree context
, tree prevfield
, const char *name
, tree type
)
10670 field
= build_decl (FIELD_DECL
, get_identifier (name
), type
);
10671 DECL_CONTEXT (field
) = context
;
10672 DECL_ALIGN (field
) = 0;
10673 DECL_USER_ALIGN (field
) = 0;
10674 if (prevfield
!= NULL_TREE
)
10675 TREE_CHAIN (prevfield
) = field
;
10681 ffecom_close_include (FILE *f
)
10683 ffecom_close_include_ (f
);
10686 /* End a compound statement (block). */
10689 ffecom_end_compstmt (void)
10691 return bison_rule_compstmt_ ();
10694 /* ffecom_end_transition -- Perform end transition on all symbols
10696 ffecom_end_transition();
10698 Calls ffecom_sym_end_transition for each global and local symbol. */
10701 ffecom_end_transition (void)
10705 if (ffe_is_ffedebug ())
10706 fprintf (dmpout
, "; end_stmt_transition\n");
10708 ffecom_list_blockdata_
= NULL
;
10709 ffecom_list_common_
= NULL
;
10711 ffesymbol_drive (ffecom_sym_end_transition
);
10712 if (ffe_is_ffedebug ())
10714 ffestorag_report ();
10717 ffecom_start_progunit_ ();
10719 for (item
= ffecom_list_blockdata_
;
10721 item
= ffebld_trail (item
))
10728 static int number
= 0;
10730 callee
= ffebld_head (item
);
10731 s
= ffebld_symter (callee
);
10732 t
= ffesymbol_hook (s
).decl_tree
;
10733 if (t
== NULL_TREE
)
10735 s
= ffecom_sym_transform_ (s
);
10736 t
= ffesymbol_hook (s
).decl_tree
;
10739 dt
= build_pointer_type (TREE_TYPE (t
));
10741 var
= build_decl (VAR_DECL
,
10742 ffecom_get_invented_identifier ("__g77_forceload_%d",
10745 DECL_EXTERNAL (var
) = 0;
10746 TREE_STATIC (var
) = 1;
10747 TREE_PUBLIC (var
) = 0;
10748 DECL_INITIAL (var
) = error_mark_node
;
10749 TREE_USED (var
) = 1;
10751 var
= start_decl (var
, FALSE
);
10753 t
= ffecom_1 (ADDR_EXPR
, dt
, t
);
10755 finish_decl (var
, t
, FALSE
);
10758 /* This handles any COMMON areas that weren't referenced but have, for
10759 example, important initial data. */
10761 for (item
= ffecom_list_common_
;
10763 item
= ffebld_trail (item
))
10764 ffecom_transform_common_ (ffebld_symter (ffebld_head (item
)));
10766 ffecom_list_common_
= NULL
;
10769 /* ffecom_exec_transition -- Perform exec transition on all symbols
10771 ffecom_exec_transition();
10773 Calls ffecom_sym_exec_transition for each global and local symbol.
10774 Make sure error updating not inhibited. */
10777 ffecom_exec_transition (void)
10781 if (ffe_is_ffedebug ())
10782 fprintf (dmpout
, "; exec_stmt_transition\n");
10784 inhibited
= ffebad_inhibit ();
10785 ffebad_set_inhibit (FALSE
);
10787 ffesymbol_drive (ffecom_sym_exec_transition
); /* Don't retract! */
10788 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
10789 if (ffe_is_ffedebug ())
10791 ffestorag_report ();
10795 ffebad_set_inhibit (TRUE
);
10798 /* Handle assignment statement.
10800 Convert dest and source using ffecom_expr, then join them
10801 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
10804 ffecom_expand_let_stmt (ffebld dest
, ffebld source
)
10811 if (ffeinfo_basictype (ffebld_info (dest
)) != FFEINFO_basictypeCHARACTER
)
10816 /* This attempts to replicate the test below, but must not be
10817 true when the test below is false. (Always err on the side
10818 of creating unused temporaries, to avoid ICEs.) */
10819 if (ffebld_op (dest
) != FFEBLD_opSYMTER
10820 || ((dest_tree
= ffesymbol_hook (ffebld_symter (dest
)).decl_tree
)
10821 && (TREE_CODE (dest_tree
) != VAR_DECL
10822 || TREE_ADDRESSABLE (dest_tree
))))
10824 ffecom_prepare_expr_ (source
, dest
);
10829 ffecom_prepare_expr_ (source
, NULL
);
10833 ffecom_prepare_expr_w (NULL_TREE
, dest
);
10835 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
10836 create a temporary through which the assignment is to take place,
10837 since MODIFY_EXPR doesn't handle partial overlap properly. */
10838 if (ffebld_basictype (dest
) == FFEINFO_basictypeCOMPLEX
10839 && ffecom_possible_partial_overlap_ (dest
, source
))
10841 assign_temp
= ffecom_make_tempvar ("complex_let",
10843 [ffebld_basictype (dest
)]
10844 [ffebld_kindtype (dest
)],
10845 FFETARGET_charactersizeNONE
,
10849 assign_temp
= NULL_TREE
;
10851 ffecom_prepare_end ();
10853 dest_tree
= ffecom_expr_w (NULL_TREE
, dest
);
10854 if (dest_tree
== error_mark_node
)
10857 if ((TREE_CODE (dest_tree
) != VAR_DECL
)
10858 || TREE_ADDRESSABLE (dest_tree
))
10859 source_tree
= ffecom_expr_ (source
, dest_tree
, dest
, &dest_used
,
10863 assert (! dest_used
);
10865 source_tree
= ffecom_expr (source
);
10867 if (source_tree
== error_mark_node
)
10871 expr_tree
= source_tree
;
10872 else if (assign_temp
)
10874 expr_tree
= ffecom_2s (MODIFY_EXPR
, void_type_node
,
10877 expand_expr_stmt (expr_tree
);
10878 expr_tree
= ffecom_2s (MODIFY_EXPR
, void_type_node
,
10883 expr_tree
= ffecom_2s (MODIFY_EXPR
, void_type_node
,
10887 expand_expr_stmt (expr_tree
);
10891 ffecom_prepare_let_char_ (ffebld_size_known (dest
), source
);
10892 ffecom_prepare_expr_w (NULL_TREE
, dest
);
10894 ffecom_prepare_end ();
10896 ffecom_char_args_ (&dest_tree
, &dest_length
, dest
);
10897 ffecom_let_char_ (dest_tree
, dest_length
, ffebld_size_known (dest
),
10901 /* ffecom_expr -- Transform expr into gcc tree
10904 ffebld expr; // FFE expression.
10905 tree = ffecom_expr(expr);
10907 Recursive descent on expr while making corresponding tree nodes and
10908 attaching type info and such. */
10911 ffecom_expr (ffebld expr
)
10913 return ffecom_expr_ (expr
, NULL_TREE
, NULL
, NULL
, FALSE
, FALSE
);
10916 /* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
10919 ffecom_expr_assign (ffebld expr
)
10921 return ffecom_expr_ (expr
, NULL_TREE
, NULL
, NULL
, TRUE
, FALSE
);
10924 /* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
10927 ffecom_expr_assign_w (ffebld expr
)
10929 return ffecom_expr_ (expr
, NULL_TREE
, NULL
, NULL
, TRUE
, FALSE
);
10932 /* Transform expr for use as into read/write tree and stabilize the
10933 reference. Not for use on CHARACTER expressions.
10935 Recursive descent on expr while making corresponding tree nodes and
10936 attaching type info and such. */
10939 ffecom_expr_rw (tree type
, ffebld expr
)
10941 assert (expr
!= NULL
);
10942 /* Different target types not yet supported. */
10943 assert (type
== NULL_TREE
|| type
== ffecom_type_expr (expr
));
10945 return stabilize_reference (ffecom_expr (expr
));
10948 /* Transform expr for use as into write tree and stabilize the
10949 reference. Not for use on CHARACTER expressions.
10951 Recursive descent on expr while making corresponding tree nodes and
10952 attaching type info and such. */
10955 ffecom_expr_w (tree type
, ffebld expr
)
10957 assert (expr
!= NULL
);
10958 /* Different target types not yet supported. */
10959 assert (type
== NULL_TREE
|| type
== ffecom_type_expr (expr
));
10961 return stabilize_reference (ffecom_expr (expr
));
10964 /* Do global stuff. */
10967 ffecom_finish_compile (void)
10969 assert (ffecom_outer_function_decl_
== NULL_TREE
);
10970 assert (current_function_decl
== NULL_TREE
);
10972 ffeglobal_drive (ffecom_finish_global_
);
10975 /* Public entry point for front end to access finish_decl. */
10978 ffecom_finish_decl (tree decl
, tree init
, bool is_top_level
)
10980 assert (!is_top_level
);
10981 finish_decl (decl
, init
, FALSE
);
10984 /* Finish a program unit. */
10987 ffecom_finish_progunit (void)
10989 ffecom_end_compstmt ();
10991 ffecom_previous_function_decl_
= current_function_decl
;
10992 ffecom_which_entrypoint_decl_
= NULL_TREE
;
10994 finish_function (0);
10997 /* Wrapper for get_identifier. pattern is sprintf-like. */
11000 ffecom_get_invented_identifier (const char *pattern
, ...)
11006 va_start (ap
, pattern
);
11007 if (vasprintf (&nam
, pattern
, ap
) == 0)
11010 decl
= get_identifier (nam
);
11012 IDENTIFIER_INVENTED (decl
) = 1;
11017 ffecom_gfrt_basictype (ffecomGfrt gfrt
)
11019 assert (gfrt
< FFECOM_gfrt
);
11021 switch (ffecom_gfrt_type_
[gfrt
])
11023 case FFECOM_rttypeVOID_
:
11024 case FFECOM_rttypeVOIDSTAR_
:
11025 return FFEINFO_basictypeNONE
;
11027 case FFECOM_rttypeFTNINT_
:
11028 return FFEINFO_basictypeINTEGER
;
11030 case FFECOM_rttypeINTEGER_
:
11031 return FFEINFO_basictypeINTEGER
;
11033 case FFECOM_rttypeLONGINT_
:
11034 return FFEINFO_basictypeINTEGER
;
11036 case FFECOM_rttypeLOGICAL_
:
11037 return FFEINFO_basictypeLOGICAL
;
11039 case FFECOM_rttypeREAL_F2C_
:
11040 case FFECOM_rttypeREAL_GNU_
:
11041 return FFEINFO_basictypeREAL
;
11043 case FFECOM_rttypeCOMPLEX_F2C_
:
11044 case FFECOM_rttypeCOMPLEX_GNU_
:
11045 return FFEINFO_basictypeCOMPLEX
;
11047 case FFECOM_rttypeDOUBLE_
:
11048 case FFECOM_rttypeDOUBLEREAL_
:
11049 return FFEINFO_basictypeREAL
;
11051 case FFECOM_rttypeDBLCMPLX_F2C_
:
11052 case FFECOM_rttypeDBLCMPLX_GNU_
:
11053 return FFEINFO_basictypeCOMPLEX
;
11055 case FFECOM_rttypeCHARACTER_
:
11056 return FFEINFO_basictypeCHARACTER
;
11059 return FFEINFO_basictypeANY
;
11064 ffecom_gfrt_kindtype (ffecomGfrt gfrt
)
11066 assert (gfrt
< FFECOM_gfrt
);
11068 switch (ffecom_gfrt_type_
[gfrt
])
11070 case FFECOM_rttypeVOID_
:
11071 case FFECOM_rttypeVOIDSTAR_
:
11072 return FFEINFO_kindtypeNONE
;
11074 case FFECOM_rttypeFTNINT_
:
11075 return FFEINFO_kindtypeINTEGER1
;
11077 case FFECOM_rttypeINTEGER_
:
11078 return FFEINFO_kindtypeINTEGER1
;
11080 case FFECOM_rttypeLONGINT_
:
11081 return FFEINFO_kindtypeINTEGER4
;
11083 case FFECOM_rttypeLOGICAL_
:
11084 return FFEINFO_kindtypeLOGICAL1
;
11086 case FFECOM_rttypeREAL_F2C_
:
11087 case FFECOM_rttypeREAL_GNU_
:
11088 return FFEINFO_kindtypeREAL1
;
11090 case FFECOM_rttypeCOMPLEX_F2C_
:
11091 case FFECOM_rttypeCOMPLEX_GNU_
:
11092 return FFEINFO_kindtypeREAL1
;
11094 case FFECOM_rttypeDOUBLE_
:
11095 case FFECOM_rttypeDOUBLEREAL_
:
11096 return FFEINFO_kindtypeREAL2
;
11098 case FFECOM_rttypeDBLCMPLX_F2C_
:
11099 case FFECOM_rttypeDBLCMPLX_GNU_
:
11100 return FFEINFO_kindtypeREAL2
;
11102 case FFECOM_rttypeCHARACTER_
:
11103 return FFEINFO_kindtypeCHARACTER1
;
11106 return FFEINFO_kindtypeANY
;
11111 ffecom_init_0 (void)
11120 tree double_ftype_double
, double_ftype_double_double
;
11121 tree float_ftype_float
, float_ftype_float_float
;
11122 tree ldouble_ftype_ldouble
, ldouble_ftype_ldouble_ldouble
;
11123 tree ffecom_tree_ptr_to_fun_type_void
;
11125 /* This block of code comes from the now-obsolete cktyps.c. It checks
11126 whether the compiler environment is buggy in known ways, some of which
11127 would, if not explicitly checked here, result in subtle bugs in g77. */
11129 if (ffe_is_do_internal_checks ())
11131 static const char names
[][12]
11133 {"bar", "bletch", "foo", "foobar"};
11138 name
= bsearch ("foo", &names
[0], ARRAY_SIZE (names
), sizeof (names
[0]),
11139 (int (*)(const void *, const void *)) strcmp
);
11140 if (name
!= &names
[2][0])
11142 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11147 ul
= strtoul ("123456789", NULL
, 10);
11148 if (ul
!= 123456789L)
11150 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11151 in proj.h" == NULL
);
11155 fl
= atof ("56.789");
11156 if ((fl
< 56.788) || (fl
> 56.79))
11158 assert ("atof not type double, fix your #include <stdio.h>"
11164 ffecom_outer_function_decl_
= NULL_TREE
;
11165 current_function_decl
= NULL_TREE
;
11166 named_labels
= NULL_TREE
;
11167 current_binding_level
= NULL_BINDING_LEVEL
;
11168 free_binding_level
= NULL_BINDING_LEVEL
;
11169 /* Make the binding_level structure for global names. */
11171 global_binding_level
= current_binding_level
;
11172 current_binding_level
->prep_state
= 2;
11174 build_common_tree_nodes (1);
11176 /* Define `int' and `char' first so that dbx will output them first. */
11177 pushdecl (build_decl (TYPE_DECL
, get_identifier ("int"),
11178 integer_type_node
));
11179 /* CHARACTER*1 is unsigned in ICHAR contexts. */
11180 char_type_node
= make_unsigned_type (CHAR_TYPE_SIZE
);
11181 pushdecl (build_decl (TYPE_DECL
, get_identifier ("char"),
11183 pushdecl (build_decl (TYPE_DECL
, get_identifier ("long int"),
11184 long_integer_type_node
));
11185 pushdecl (build_decl (TYPE_DECL
, get_identifier ("unsigned int"),
11186 unsigned_type_node
));
11187 pushdecl (build_decl (TYPE_DECL
, get_identifier ("long unsigned int"),
11188 long_unsigned_type_node
));
11189 pushdecl (build_decl (TYPE_DECL
, get_identifier ("long long int"),
11190 long_long_integer_type_node
));
11191 pushdecl (build_decl (TYPE_DECL
, get_identifier ("long long unsigned int"),
11192 long_long_unsigned_type_node
));
11193 pushdecl (build_decl (TYPE_DECL
, get_identifier ("short int"),
11194 short_integer_type_node
));
11195 pushdecl (build_decl (TYPE_DECL
, get_identifier ("short unsigned int"),
11196 short_unsigned_type_node
));
11198 /* Set the sizetype before we make other types. This *should* be the
11199 first type we create. */
11202 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE
))));
11203 ffecom_typesize_pointer_
11204 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype
)) / BITS_PER_UNIT
;
11206 build_common_tree_nodes_2 (0);
11208 /* Define both `signed char' and `unsigned char'. */
11209 pushdecl (build_decl (TYPE_DECL
, get_identifier ("signed char"),
11210 signed_char_type_node
));
11212 pushdecl (build_decl (TYPE_DECL
, get_identifier ("unsigned char"),
11213 unsigned_char_type_node
));
11215 pushdecl (build_decl (TYPE_DECL
, get_identifier ("float"),
11217 pushdecl (build_decl (TYPE_DECL
, get_identifier ("double"),
11218 double_type_node
));
11219 pushdecl (build_decl (TYPE_DECL
, get_identifier ("long double"),
11220 long_double_type_node
));
11222 /* For now, override what build_common_tree_nodes has done. */
11223 complex_integer_type_node
= ffecom_make_complex_type_ (integer_type_node
);
11224 complex_float_type_node
= ffecom_make_complex_type_ (float_type_node
);
11225 complex_double_type_node
= ffecom_make_complex_type_ (double_type_node
);
11226 complex_long_double_type_node
11227 = ffecom_make_complex_type_ (long_double_type_node
);
11229 pushdecl (build_decl (TYPE_DECL
, get_identifier ("complex int"),
11230 complex_integer_type_node
));
11231 pushdecl (build_decl (TYPE_DECL
, get_identifier ("complex float"),
11232 complex_float_type_node
));
11233 pushdecl (build_decl (TYPE_DECL
, get_identifier ("complex double"),
11234 complex_double_type_node
));
11235 pushdecl (build_decl (TYPE_DECL
, get_identifier ("complex long double"),
11236 complex_long_double_type_node
));
11238 pushdecl (build_decl (TYPE_DECL
, get_identifier ("void"),
11240 /* We are not going to have real types in C with less than byte alignment,
11241 so we might as well not have any types that claim to have it. */
11242 TYPE_ALIGN (void_type_node
) = BITS_PER_UNIT
;
11243 TYPE_USER_ALIGN (void_type_node
) = 0;
11245 string_type_node
= build_pointer_type (char_type_node
);
11247 ffecom_tree_fun_type_void
11248 = build_function_type (void_type_node
, NULL_TREE
);
11250 ffecom_tree_ptr_to_fun_type_void
11251 = build_pointer_type (ffecom_tree_fun_type_void
);
11253 endlink
= tree_cons (NULL_TREE
, void_type_node
, NULL_TREE
);
11255 t
= tree_cons (NULL_TREE
, float_type_node
, endlink
);
11256 float_ftype_float
= build_function_type (float_type_node
, t
);
11257 t
= tree_cons (NULL_TREE
, float_type_node
, t
);
11258 float_ftype_float_float
= build_function_type (float_type_node
, t
);
11260 t
= tree_cons (NULL_TREE
, double_type_node
, endlink
);
11261 double_ftype_double
= build_function_type (double_type_node
, t
);
11262 t
= tree_cons (NULL_TREE
, double_type_node
, t
);
11263 double_ftype_double_double
= build_function_type (double_type_node
, t
);
11265 t
= tree_cons (NULL_TREE
, long_double_type_node
, endlink
);
11266 ldouble_ftype_ldouble
= build_function_type (long_double_type_node
, t
);
11267 t
= tree_cons (NULL_TREE
, long_double_type_node
, t
);
11268 ldouble_ftype_ldouble_ldouble
= build_function_type (long_double_type_node
,
11271 for (i
= 0; ((size_t) i
) < ARRAY_SIZE (ffecom_tree_type
); ++i
)
11272 for (j
= 0; ((size_t) j
) < ARRAY_SIZE (ffecom_tree_type
[0]); ++j
)
11274 ffecom_tree_type
[i
][j
] = NULL_TREE
;
11275 ffecom_tree_fun_type
[i
][j
] = NULL_TREE
;
11276 ffecom_tree_ptr_to_fun_type
[i
][j
] = NULL_TREE
;
11277 ffecom_f2c_typecode_
[i
][j
] = -1;
11280 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11281 to size FLOAT_TYPE_SIZE because they have to be the same size as
11282 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11283 Compiler options and other such stuff that change the ways these
11284 types are set should not affect this particular setup. */
11286 ffecom_tree_type
[FFEINFO_basictypeINTEGER
][FFEINFO_kindtypeINTEGER1
]
11287 = t
= make_signed_type (FLOAT_TYPE_SIZE
);
11288 pushdecl (build_decl (TYPE_DECL
, get_identifier ("integer"),
11290 type
= ffetype_new ();
11292 ffeinfo_set_type (FFEINFO_basictypeINTEGER
, FFEINFO_kindtypeINTEGER1
,
11294 ffetype_set_ams (type
,
11295 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11296 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11297 ffetype_set_star (base_type
,
11298 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11300 ffetype_set_kind (base_type
, 1, type
);
11301 ffecom_typesize_integer1_
= ffetype_size (type
);
11302 assert (ffetype_size (type
) == sizeof (ffetargetInteger1
));
11304 ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][FFEINFO_kindtypeINTEGER1
]
11305 = t
= make_unsigned_type (FLOAT_TYPE_SIZE
); /* HOLLERITH means unsigned. */
11306 pushdecl (build_decl (TYPE_DECL
, get_identifier ("unsigned"),
11309 ffecom_tree_type
[FFEINFO_basictypeINTEGER
][FFEINFO_kindtypeINTEGER2
]
11310 = t
= make_signed_type (CHAR_TYPE_SIZE
);
11311 pushdecl (build_decl (TYPE_DECL
, get_identifier ("byte"),
11313 type
= ffetype_new ();
11314 ffeinfo_set_type (FFEINFO_basictypeINTEGER
, FFEINFO_kindtypeINTEGER2
,
11316 ffetype_set_ams (type
,
11317 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11318 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11319 ffetype_set_star (base_type
,
11320 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11322 ffetype_set_kind (base_type
, 3, type
);
11323 assert (ffetype_size (type
) == sizeof (ffetargetInteger2
));
11325 ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][FFEINFO_kindtypeINTEGER2
]
11326 = t
= make_unsigned_type (CHAR_TYPE_SIZE
);
11327 pushdecl (build_decl (TYPE_DECL
, get_identifier ("unsigned byte"),
11330 ffecom_tree_type
[FFEINFO_basictypeINTEGER
][FFEINFO_kindtypeINTEGER3
]
11331 = t
= make_signed_type (CHAR_TYPE_SIZE
* 2);
11332 pushdecl (build_decl (TYPE_DECL
, get_identifier ("word"),
11334 type
= ffetype_new ();
11335 ffeinfo_set_type (FFEINFO_basictypeINTEGER
, FFEINFO_kindtypeINTEGER3
,
11337 ffetype_set_ams (type
,
11338 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11339 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11340 ffetype_set_star (base_type
,
11341 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11343 ffetype_set_kind (base_type
, 6, type
);
11344 assert (ffetype_size (type
) == sizeof (ffetargetInteger3
));
11346 ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][FFEINFO_kindtypeINTEGER3
]
11347 = t
= make_unsigned_type (CHAR_TYPE_SIZE
* 2);
11348 pushdecl (build_decl (TYPE_DECL
, get_identifier ("unsigned word"),
11351 ffecom_tree_type
[FFEINFO_basictypeINTEGER
][FFEINFO_kindtypeINTEGER4
]
11352 = t
= make_signed_type (FLOAT_TYPE_SIZE
* 2);
11353 pushdecl (build_decl (TYPE_DECL
, get_identifier ("integer4"),
11355 type
= ffetype_new ();
11356 ffeinfo_set_type (FFEINFO_basictypeINTEGER
, FFEINFO_kindtypeINTEGER4
,
11358 ffetype_set_ams (type
,
11359 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11360 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11361 ffetype_set_star (base_type
,
11362 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11364 ffetype_set_kind (base_type
, 2, type
);
11365 assert (ffetype_size (type
) == sizeof (ffetargetInteger4
));
11367 ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][FFEINFO_kindtypeINTEGER4
]
11368 = t
= make_unsigned_type (FLOAT_TYPE_SIZE
* 2);
11369 pushdecl (build_decl (TYPE_DECL
, get_identifier ("unsigned4"),
11373 if (ffe_is_do_internal_checks ()
11374 && LONG_TYPE_SIZE
!= FLOAT_TYPE_SIZE
11375 && LONG_TYPE_SIZE
!= CHAR_TYPE_SIZE
11376 && LONG_TYPE_SIZE
!= SHORT_TYPE_SIZE
11377 && LONG_TYPE_SIZE
!= LONG_LONG_TYPE_SIZE
)
11379 fprintf (stderr
, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11384 ffecom_tree_type
[FFEINFO_basictypeLOGICAL
][FFEINFO_kindtypeLOGICAL1
]
11385 = t
= make_signed_type (FLOAT_TYPE_SIZE
);
11386 pushdecl (build_decl (TYPE_DECL
, get_identifier ("logical"),
11388 type
= ffetype_new ();
11390 ffeinfo_set_type (FFEINFO_basictypeLOGICAL
, FFEINFO_kindtypeLOGICAL1
,
11392 ffetype_set_ams (type
,
11393 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11394 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11395 ffetype_set_star (base_type
,
11396 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11398 ffetype_set_kind (base_type
, 1, type
);
11399 assert (ffetype_size (type
) == sizeof (ffetargetLogical1
));
11401 ffecom_tree_type
[FFEINFO_basictypeLOGICAL
][FFEINFO_kindtypeLOGICAL2
]
11402 = t
= make_signed_type (CHAR_TYPE_SIZE
);
11403 pushdecl (build_decl (TYPE_DECL
, get_identifier ("logical2"),
11405 type
= ffetype_new ();
11406 ffeinfo_set_type (FFEINFO_basictypeLOGICAL
, FFEINFO_kindtypeLOGICAL2
,
11408 ffetype_set_ams (type
,
11409 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11410 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11411 ffetype_set_star (base_type
,
11412 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11414 ffetype_set_kind (base_type
, 3, type
);
11415 assert (ffetype_size (type
) == sizeof (ffetargetLogical2
));
11417 ffecom_tree_type
[FFEINFO_basictypeLOGICAL
][FFEINFO_kindtypeLOGICAL3
]
11418 = t
= make_signed_type (CHAR_TYPE_SIZE
* 2);
11419 pushdecl (build_decl (TYPE_DECL
, get_identifier ("logical3"),
11421 type
= ffetype_new ();
11422 ffeinfo_set_type (FFEINFO_basictypeLOGICAL
, FFEINFO_kindtypeLOGICAL3
,
11424 ffetype_set_ams (type
,
11425 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11426 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11427 ffetype_set_star (base_type
,
11428 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11430 ffetype_set_kind (base_type
, 6, type
);
11431 assert (ffetype_size (type
) == sizeof (ffetargetLogical3
));
11433 ffecom_tree_type
[FFEINFO_basictypeLOGICAL
][FFEINFO_kindtypeLOGICAL4
]
11434 = t
= make_signed_type (FLOAT_TYPE_SIZE
* 2);
11435 pushdecl (build_decl (TYPE_DECL
, get_identifier ("logical4"),
11437 type
= ffetype_new ();
11438 ffeinfo_set_type (FFEINFO_basictypeLOGICAL
, FFEINFO_kindtypeLOGICAL4
,
11440 ffetype_set_ams (type
,
11441 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11442 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11443 ffetype_set_star (base_type
,
11444 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11446 ffetype_set_kind (base_type
, 2, type
);
11447 assert (ffetype_size (type
) == sizeof (ffetargetLogical4
));
11449 ffecom_tree_type
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL1
]
11450 = t
= make_node (REAL_TYPE
);
11451 TYPE_PRECISION (t
) = FLOAT_TYPE_SIZE
;
11452 pushdecl (build_decl (TYPE_DECL
, get_identifier ("real"),
11455 type
= ffetype_new ();
11457 ffeinfo_set_type (FFEINFO_basictypeREAL
, FFEINFO_kindtypeREAL1
,
11459 ffetype_set_ams (type
,
11460 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11461 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11462 ffetype_set_star (base_type
,
11463 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11465 ffetype_set_kind (base_type
, 1, type
);
11466 ffecom_f2c_typecode_
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL1
]
11467 = FFETARGET_f2cTYREAL
;
11468 assert (ffetype_size (type
) == sizeof (ffetargetReal1
));
11470 ffecom_tree_type
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREALDOUBLE
]
11471 = t
= make_node (REAL_TYPE
);
11472 TYPE_PRECISION (t
) = FLOAT_TYPE_SIZE
* 2; /* Always twice REAL. */
11473 pushdecl (build_decl (TYPE_DECL
, get_identifier ("double precision"),
11476 type
= ffetype_new ();
11477 ffeinfo_set_type (FFEINFO_basictypeREAL
, FFEINFO_kindtypeREALDOUBLE
,
11479 ffetype_set_ams (type
,
11480 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11481 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11482 ffetype_set_star (base_type
,
11483 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11485 ffetype_set_kind (base_type
, 2, type
);
11486 ffecom_f2c_typecode_
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL2
]
11487 = FFETARGET_f2cTYDREAL
;
11488 assert (ffetype_size (type
) == sizeof (ffetargetReal2
));
11490 ffecom_tree_type
[FFEINFO_basictypeCOMPLEX
][FFEINFO_kindtypeREAL1
]
11491 = t
= ffecom_make_complex_type_ (ffecom_tree_type
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL1
]);
11492 pushdecl (build_decl (TYPE_DECL
, get_identifier ("complex"),
11494 type
= ffetype_new ();
11496 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX
, FFEINFO_kindtypeREAL1
,
11498 ffetype_set_ams (type
,
11499 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11500 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11501 ffetype_set_star (base_type
,
11502 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11504 ffetype_set_kind (base_type
, 1, type
);
11505 ffecom_f2c_typecode_
[FFEINFO_basictypeCOMPLEX
][FFEINFO_kindtypeREAL1
]
11506 = FFETARGET_f2cTYCOMPLEX
;
11507 assert (ffetype_size (type
) == sizeof (ffetargetComplex1
));
11509 ffecom_tree_type
[FFEINFO_basictypeCOMPLEX
][FFEINFO_kindtypeREALDOUBLE
]
11510 = t
= ffecom_make_complex_type_ (ffecom_tree_type
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL2
]);
11511 pushdecl (build_decl (TYPE_DECL
, get_identifier ("double complex"),
11513 type
= ffetype_new ();
11514 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX
, FFEINFO_kindtypeREALDOUBLE
,
11516 ffetype_set_ams (type
,
11517 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11518 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11519 ffetype_set_star (base_type
,
11520 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11522 ffetype_set_kind (base_type
, 2,
11524 ffecom_f2c_typecode_
[FFEINFO_basictypeCOMPLEX
][FFEINFO_kindtypeREAL2
]
11525 = FFETARGET_f2cTYDCOMPLEX
;
11526 assert (ffetype_size (type
) == sizeof (ffetargetComplex2
));
11528 /* Make function and ptr-to-function types for non-CHARACTER types. */
11530 for (i
= 0; ((size_t) i
) < ARRAY_SIZE (ffecom_tree_type
); ++i
)
11531 for (j
= 0; ((size_t) j
) < ARRAY_SIZE (ffecom_tree_type
[0]); ++j
)
11533 if ((t
= ffecom_tree_type
[i
][j
]) != NULL_TREE
)
11535 if (i
== FFEINFO_basictypeINTEGER
)
11537 /* Figure out the smallest INTEGER type that can hold
11538 a pointer on this machine. */
11539 if (GET_MODE_SIZE (TYPE_MODE (t
))
11540 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node
))))
11542 if ((ffecom_pointer_kind_
== FFEINFO_kindtypeNONE
)
11543 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type
[i
][ffecom_pointer_kind_
]))
11544 > GET_MODE_SIZE (TYPE_MODE (t
))))
11545 ffecom_pointer_kind_
= j
;
11548 else if (i
== FFEINFO_basictypeCOMPLEX
)
11549 t
= void_type_node
;
11550 /* For f2c compatibility, REAL functions are really
11551 implemented as DOUBLE PRECISION. */
11552 else if ((i
== FFEINFO_basictypeREAL
)
11553 && (j
== FFEINFO_kindtypeREAL1
))
11554 t
= ffecom_tree_type
11555 [FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL2
];
11557 t
= ffecom_tree_fun_type
[i
][j
] = build_function_type (t
,
11559 ffecom_tree_ptr_to_fun_type
[i
][j
] = build_pointer_type (t
);
11563 /* Set up pointer types. */
11565 if (ffecom_pointer_kind_
== FFEINFO_basictypeNONE
)
11566 fatal_error ("no INTEGER type can hold a pointer on this configuration");
11567 else if (0 && ffe_is_do_internal_checks ())
11568 fprintf (stderr
, "Pointer type kt=%d\n", ffecom_pointer_kind_
);
11569 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER
,
11570 FFEINFO_kindtypeINTEGERDEFAULT
),
11572 ffeinfo_type (FFEINFO_basictypeINTEGER
,
11573 ffecom_pointer_kind_
));
11575 if (ffe_is_ugly_assign ())
11576 ffecom_label_kind_
= ffecom_pointer_kind_
; /* Require ASSIGN etc to this. */
11578 ffecom_label_kind_
= FFEINFO_kindtypeINTEGERDEFAULT
;
11579 if (0 && ffe_is_do_internal_checks ())
11580 fprintf (stderr
, "Label type kt=%d\n", ffecom_label_kind_
);
11582 ffecom_integer_type_node
11583 = ffecom_tree_type
[FFEINFO_basictypeINTEGER
][FFEINFO_kindtypeINTEGER1
];
11584 ffecom_integer_zero_node
= convert (ffecom_integer_type_node
,
11585 integer_zero_node
);
11586 ffecom_integer_one_node
= convert (ffecom_integer_type_node
,
11589 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11590 Turns out that by TYLONG, runtime/libI77/lio.h really means
11591 "whatever size an ftnint is". For consistency and sanity,
11592 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
11593 all are INTEGER, which we also make out of whatever back-end
11594 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
11595 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
11596 accommodate machines like the Alpha. Note that this suggests
11597 f2c and libf2c are missing a distinction perhaps needed on
11598 some machines between "int" and "long int". -- burley 0.5.5 950215 */
11600 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER
, FLOAT_TYPE_SIZE
,
11601 FFETARGET_f2cTYLONG
);
11602 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER
, SHORT_TYPE_SIZE
,
11603 FFETARGET_f2cTYSHORT
);
11604 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER
, CHAR_TYPE_SIZE
,
11605 FFETARGET_f2cTYINT1
);
11606 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER
, LONG_LONG_TYPE_SIZE
,
11607 FFETARGET_f2cTYQUAD
);
11608 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL
, FLOAT_TYPE_SIZE
,
11609 FFETARGET_f2cTYLOGICAL
);
11610 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL
, SHORT_TYPE_SIZE
,
11611 FFETARGET_f2cTYLOGICAL2
);
11612 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL
, CHAR_TYPE_SIZE
,
11613 FFETARGET_f2cTYLOGICAL1
);
11614 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
11615 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL
, LONG_LONG_TYPE_SIZE
,
11616 FFETARGET_f2cTYQUAD
);
11618 /* CHARACTER stuff is all special-cased, so it is not handled in the above
11619 loop. CHARACTER items are built as arrays of unsigned char. */
11621 ffecom_tree_type
[FFEINFO_basictypeCHARACTER
]
11622 [FFEINFO_kindtypeCHARACTER1
] = t
= char_type_node
;
11623 type
= ffetype_new ();
11625 ffeinfo_set_type (FFEINFO_basictypeCHARACTER
,
11626 FFEINFO_kindtypeCHARACTER1
,
11628 ffetype_set_ams (type
,
11629 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11630 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11631 ffetype_set_kind (base_type
, 1, type
);
11632 assert (ffetype_size (type
)
11633 == sizeof (((ffetargetCharacter1
) { 0, NULL
}).text
[0]));
11635 ffecom_tree_fun_type
[FFEINFO_basictypeCHARACTER
]
11636 [FFEINFO_kindtypeCHARACTER1
] = ffecom_tree_fun_type_void
;
11637 ffecom_tree_ptr_to_fun_type
[FFEINFO_basictypeCHARACTER
]
11638 [FFEINFO_kindtypeCHARACTER1
]
11639 = ffecom_tree_ptr_to_fun_type_void
;
11640 ffecom_f2c_typecode_
[FFEINFO_basictypeCHARACTER
][FFEINFO_kindtypeCHARACTER1
]
11641 = FFETARGET_f2cTYCHAR
;
11643 ffecom_f2c_typecode_
[FFEINFO_basictypeANY
][FFEINFO_kindtypeANY
]
11646 /* Make multi-return-value type and fields. */
11648 ffecom_multi_type_node_
= make_node (UNION_TYPE
);
11652 for (i
= 0; ((size_t) i
) < ARRAY_SIZE (ffecom_tree_type
); ++i
)
11653 for (j
= 0; ((size_t) j
) < ARRAY_SIZE (ffecom_tree_type
[0]); ++j
)
11657 if (ffecom_tree_type
[i
][j
] == NULL_TREE
)
11658 continue; /* Not supported. */
11659 sprintf (&name
[0], "bt_%s_kt_%s",
11660 ffeinfo_basictype_string ((ffeinfoBasictype
) i
),
11661 ffeinfo_kindtype_string ((ffeinfoKindtype
) j
));
11662 ffecom_multi_fields_
[i
][j
] = build_decl (FIELD_DECL
,
11663 get_identifier (name
),
11664 ffecom_tree_type
[i
][j
]);
11665 DECL_CONTEXT (ffecom_multi_fields_
[i
][j
])
11666 = ffecom_multi_type_node_
;
11667 DECL_ALIGN (ffecom_multi_fields_
[i
][j
]) = 0;
11668 DECL_USER_ALIGN (ffecom_multi_fields_
[i
][j
]) = 0;
11669 TREE_CHAIN (ffecom_multi_fields_
[i
][j
]) = field
;
11670 field
= ffecom_multi_fields_
[i
][j
];
11673 TYPE_FIELDS (ffecom_multi_type_node_
) = field
;
11674 layout_type (ffecom_multi_type_node_
);
11676 /* Subroutines usually return integer because they might have alternate
11679 ffecom_tree_subr_type
11680 = build_function_type (integer_type_node
, NULL_TREE
);
11681 ffecom_tree_ptr_to_subr_type
11682 = build_pointer_type (ffecom_tree_subr_type
);
11683 ffecom_tree_blockdata_type
11684 = build_function_type (void_type_node
, NULL_TREE
);
11686 builtin_function ("__builtin_atanf", float_ftype_float
,
11687 BUILT_IN_ATANF
, BUILT_IN_NORMAL
, "atanf", NULL_TREE
);
11688 builtin_function ("__builtin_atan", double_ftype_double
,
11689 BUILT_IN_ATAN
, BUILT_IN_NORMAL
, "atan", NULL_TREE
);
11690 builtin_function ("__builtin_atanl", ldouble_ftype_ldouble
,
11691 BUILT_IN_ATANL
, BUILT_IN_NORMAL
, "atanl", NULL_TREE
);
11693 builtin_function ("__builtin_atan2f", float_ftype_float_float
,
11694 BUILT_IN_ATAN2F
, BUILT_IN_NORMAL
, "atan2f", NULL_TREE
);
11695 builtin_function ("__builtin_atan2", double_ftype_double_double
,
11696 BUILT_IN_ATAN2
, BUILT_IN_NORMAL
, "atan2", NULL_TREE
);
11697 builtin_function ("__builtin_atan2l", ldouble_ftype_ldouble_ldouble
,
11698 BUILT_IN_ATAN2L
, BUILT_IN_NORMAL
, "atan2l", NULL_TREE
);
11700 builtin_function ("__builtin_cosf", float_ftype_float
,
11701 BUILT_IN_COSF
, BUILT_IN_NORMAL
, "cosf", NULL_TREE
);
11702 builtin_function ("__builtin_cos", double_ftype_double
,
11703 BUILT_IN_COS
, BUILT_IN_NORMAL
, "cos", NULL_TREE
);
11704 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble
,
11705 BUILT_IN_COSL
, BUILT_IN_NORMAL
, "cosl", NULL_TREE
);
11707 builtin_function ("__builtin_expf", float_ftype_float
,
11708 BUILT_IN_EXPF
, BUILT_IN_NORMAL
, "expf", NULL_TREE
);
11709 builtin_function ("__builtin_exp", double_ftype_double
,
11710 BUILT_IN_EXP
, BUILT_IN_NORMAL
, "exp", NULL_TREE
);
11711 builtin_function ("__builtin_expl", ldouble_ftype_ldouble
,
11712 BUILT_IN_EXPL
, BUILT_IN_NORMAL
, "expl", NULL_TREE
);
11714 builtin_function ("__builtin_floorf", float_ftype_float
,
11715 BUILT_IN_FLOORF
, BUILT_IN_NORMAL
, "floorf", NULL_TREE
);
11716 builtin_function ("__builtin_floor", double_ftype_double
,
11717 BUILT_IN_FLOOR
, BUILT_IN_NORMAL
, "floor", NULL_TREE
);
11718 builtin_function ("__builtin_floorl", ldouble_ftype_ldouble
,
11719 BUILT_IN_FLOORL
, BUILT_IN_NORMAL
, "floorl", NULL_TREE
);
11721 builtin_function ("__builtin_fmodf", float_ftype_float_float
,
11722 BUILT_IN_FMODF
, BUILT_IN_NORMAL
, "fmodf", NULL_TREE
);
11723 builtin_function ("__builtin_fmod", double_ftype_double_double
,
11724 BUILT_IN_FMOD
, BUILT_IN_NORMAL
, "fmod", NULL_TREE
);
11725 builtin_function ("__builtin_fmodl", ldouble_ftype_ldouble_ldouble
,
11726 BUILT_IN_FMODL
, BUILT_IN_NORMAL
, "fmodl", NULL_TREE
);
11728 builtin_function ("__builtin_logf", float_ftype_float
,
11729 BUILT_IN_LOGF
, BUILT_IN_NORMAL
, "logf", NULL_TREE
);
11730 builtin_function ("__builtin_log", double_ftype_double
,
11731 BUILT_IN_LOG
, BUILT_IN_NORMAL
, "log", NULL_TREE
);
11732 builtin_function ("__builtin_logl", ldouble_ftype_ldouble
,
11733 BUILT_IN_LOGL
, BUILT_IN_NORMAL
, "logl", NULL_TREE
);
11735 builtin_function ("__builtin_powf", float_ftype_float_float
,
11736 BUILT_IN_POWF
, BUILT_IN_NORMAL
, "powf", NULL_TREE
);
11737 builtin_function ("__builtin_pow", double_ftype_double_double
,
11738 BUILT_IN_POW
, BUILT_IN_NORMAL
, "pow", NULL_TREE
);
11739 builtin_function ("__builtin_powl", ldouble_ftype_ldouble_ldouble
,
11740 BUILT_IN_POWL
, BUILT_IN_NORMAL
, "powl", NULL_TREE
);
11742 builtin_function ("__builtin_sinf", float_ftype_float
,
11743 BUILT_IN_SINF
, BUILT_IN_NORMAL
, "sinf", NULL_TREE
);
11744 builtin_function ("__builtin_sin", double_ftype_double
,
11745 BUILT_IN_SIN
, BUILT_IN_NORMAL
, "sin", NULL_TREE
);
11746 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble
,
11747 BUILT_IN_SINL
, BUILT_IN_NORMAL
, "sinl", NULL_TREE
);
11749 builtin_function ("__builtin_sqrtf", float_ftype_float
,
11750 BUILT_IN_SQRTF
, BUILT_IN_NORMAL
, "sqrtf", NULL_TREE
);
11751 builtin_function ("__builtin_sqrt", double_ftype_double
,
11752 BUILT_IN_SQRT
, BUILT_IN_NORMAL
, "sqrt", NULL_TREE
);
11753 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble
,
11754 BUILT_IN_SQRTL
, BUILT_IN_NORMAL
, "sqrtl", NULL_TREE
);
11756 builtin_function ("__builtin_tanf", float_ftype_float
,
11757 BUILT_IN_TANF
, BUILT_IN_NORMAL
, "tanf", NULL_TREE
);
11758 builtin_function ("__builtin_tan", double_ftype_double
,
11759 BUILT_IN_TAN
, BUILT_IN_NORMAL
, "tan", NULL_TREE
);
11760 builtin_function ("__builtin_tanl", ldouble_ftype_ldouble
,
11761 BUILT_IN_TANL
, BUILT_IN_NORMAL
, "tanl", NULL_TREE
);
11763 pedantic_lvalues
= FALSE
;
11765 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node
,
11768 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node
,
11771 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node
,
11774 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node
,
11775 FFECOM_f2cDOUBLEREAL
,
11777 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node
,
11780 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node
,
11781 FFECOM_f2cDOUBLECOMPLEX
,
11783 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node
,
11786 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node
,
11789 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node
,
11792 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node
,
11795 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node
,
11799 ffecom_f2c_ftnlen_zero_node
11800 = convert (ffecom_f2c_ftnlen_type_node
, integer_zero_node
);
11802 ffecom_f2c_ftnlen_one_node
11803 = convert (ffecom_f2c_ftnlen_type_node
, integer_one_node
);
11805 ffecom_f2c_ftnlen_two_node
= build_int_2 (2, 0);
11806 TREE_TYPE (ffecom_f2c_ftnlen_two_node
) = ffecom_integer_type_node
;
11808 ffecom_f2c_ptr_to_ftnlen_type_node
11809 = build_pointer_type (ffecom_f2c_ftnlen_type_node
);
11811 ffecom_f2c_ptr_to_ftnint_type_node
11812 = build_pointer_type (ffecom_f2c_ftnint_type_node
);
11814 ffecom_f2c_ptr_to_integer_type_node
11815 = build_pointer_type (ffecom_f2c_integer_type_node
);
11817 ffecom_f2c_ptr_to_real_type_node
11818 = build_pointer_type (ffecom_f2c_real_type_node
);
11820 ffecom_float_zero_
= build_real (float_type_node
, dconst0
);
11821 ffecom_double_zero_
= build_real (double_type_node
, dconst0
);
11822 ffecom_float_half_
= build_real (float_type_node
, dconsthalf
);
11823 ffecom_double_half_
= build_real (double_type_node
, dconsthalf
);
11825 /* Do "extern int xargc;". */
11827 ffecom_tree_xargc_
= build_decl (VAR_DECL
,
11828 get_identifier ("f__xargc"),
11829 integer_type_node
);
11830 DECL_EXTERNAL (ffecom_tree_xargc_
) = 1;
11831 TREE_STATIC (ffecom_tree_xargc_
) = 1;
11832 TREE_PUBLIC (ffecom_tree_xargc_
) = 1;
11833 ffecom_tree_xargc_
= start_decl (ffecom_tree_xargc_
, FALSE
);
11834 finish_decl (ffecom_tree_xargc_
, NULL_TREE
, FALSE
);
11836 #if 0 /* This is being fixed, and seems to be working now. */
11837 if ((FLOAT_TYPE_SIZE
!= 32)
11838 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node
))) != 32))
11840 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
11841 (int) FLOAT_TYPE_SIZE
);
11842 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
11843 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node
))));
11844 warning ("properly unless they all are 32 bits wide");
11845 warning ("Please keep this in mind before you report bugs.");
11849 #if 0 /* Code in ste.c that would crash has been commented out. */
11850 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node
)
11851 < TYPE_PRECISION (string_type_node
))
11852 /* I/O will probably crash. */
11853 warning ("configuration: char * holds %d bits, but ftnlen only %d",
11854 TYPE_PRECISION (string_type_node
),
11855 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node
));
11858 #if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
11859 if (TYPE_PRECISION (ffecom_integer_type_node
)
11860 < TYPE_PRECISION (string_type_node
))
11861 /* ASSIGN 10 TO I will crash. */
11862 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
11863 ASSIGN statement might fail",
11864 TYPE_PRECISION (string_type_node
),
11865 TYPE_PRECISION (ffecom_integer_type_node
));
11869 /* ffecom_init_2 -- Initialize
11871 ffecom_init_2(); */
11874 ffecom_init_2 (void)
11876 assert (ffecom_outer_function_decl_
== NULL_TREE
);
11877 assert (current_function_decl
== NULL_TREE
);
11878 assert (ffecom_which_entrypoint_decl_
== NULL_TREE
);
11880 ffecom_master_arglist_
= NULL
;
11882 ffecom_primary_entry_
= NULL
;
11883 ffecom_is_altreturning_
= FALSE
;
11884 ffecom_func_result_
= NULL_TREE
;
11885 ffecom_multi_retval_
= NULL_TREE
;
11888 /* ffecom_list_expr -- Transform list of exprs into gcc tree
11891 ffebld expr; // FFE opITEM list.
11892 tree = ffecom_list_expr(expr);
11894 List of actual args is transformed into corresponding gcc backend list. */
11897 ffecom_list_expr (ffebld expr
)
11900 tree
*plist
= &list
;
11901 tree trail
= NULL_TREE
; /* Append char length args here. */
11902 tree
*ptrail
= &trail
;
11905 while (expr
!= NULL
)
11907 tree texpr
= ffecom_arg_expr (ffebld_head (expr
), &length
);
11909 if (texpr
== error_mark_node
)
11910 return error_mark_node
;
11912 *plist
= build_tree_list (NULL_TREE
, texpr
);
11913 plist
= &TREE_CHAIN (*plist
);
11914 expr
= ffebld_trail (expr
);
11915 if (length
!= NULL_TREE
)
11917 *ptrail
= build_tree_list (NULL_TREE
, length
);
11918 ptrail
= &TREE_CHAIN (*ptrail
);
11927 /* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
11930 ffebld expr; // FFE opITEM list.
11931 tree = ffecom_list_ptr_to_expr(expr);
11933 List of actual args is transformed into corresponding gcc backend list for
11934 use in calling an external procedure (vs. a statement function). */
11937 ffecom_list_ptr_to_expr (ffebld expr
)
11940 tree
*plist
= &list
;
11941 tree trail
= NULL_TREE
; /* Append char length args here. */
11942 tree
*ptrail
= &trail
;
11945 while (expr
!= NULL
)
11947 tree texpr
= ffecom_arg_ptr_to_expr (ffebld_head (expr
), &length
);
11949 if (texpr
== error_mark_node
)
11950 return error_mark_node
;
11952 *plist
= build_tree_list (NULL_TREE
, texpr
);
11953 plist
= &TREE_CHAIN (*plist
);
11954 expr
= ffebld_trail (expr
);
11955 if (length
!= NULL_TREE
)
11957 *ptrail
= build_tree_list (NULL_TREE
, length
);
11958 ptrail
= &TREE_CHAIN (*ptrail
);
11967 /* Obtain gcc's LABEL_DECL tree for label. */
11970 ffecom_lookup_label (ffelab label
)
11974 if (ffelab_hook (label
) == NULL_TREE
)
11976 char labelname
[16];
11978 switch (ffelab_type (label
))
11980 case FFELAB_typeLOOPEND
:
11981 case FFELAB_typeNOTLOOP
:
11982 case FFELAB_typeENDIF
:
11983 sprintf (labelname
, "%" ffelabValue_f
"u", ffelab_value (label
));
11984 glabel
= build_decl (LABEL_DECL
, get_identifier (labelname
),
11986 DECL_CONTEXT (glabel
) = current_function_decl
;
11987 DECL_MODE (glabel
) = VOIDmode
;
11990 case FFELAB_typeFORMAT
:
11991 glabel
= build_decl (VAR_DECL
,
11992 ffecom_get_invented_identifier
11993 ("__g77_format_%d", (int) ffelab_value (label
)),
11994 build_type_variant (build_array_type
11998 TREE_CONSTANT (glabel
) = 1;
11999 TREE_STATIC (glabel
) = 1;
12000 DECL_CONTEXT (glabel
) = current_function_decl
;
12001 DECL_INITIAL (glabel
) = NULL
;
12002 make_decl_rtl (glabel
, NULL
);
12003 expand_decl (glabel
);
12005 ffecom_save_tree_forever (glabel
);
12009 case FFELAB_typeANY
:
12010 glabel
= error_mark_node
;
12014 assert ("bad label type" == NULL
);
12018 ffelab_set_hook (label
, glabel
);
12022 glabel
= ffelab_hook (label
);
12028 /* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12029 a single source specification (as in the fourth argument of MVBITS).
12030 If the type is NULL_TREE, the type of lhs is used to make the type of
12031 the MODIFY_EXPR. */
12034 ffecom_modify (tree newtype
, tree lhs
, tree rhs
)
12036 if (lhs
== error_mark_node
|| rhs
== error_mark_node
)
12037 return error_mark_node
;
12039 if (newtype
== NULL_TREE
)
12040 newtype
= TREE_TYPE (lhs
);
12042 if (TREE_SIDE_EFFECTS (lhs
))
12043 lhs
= stabilize_reference (lhs
);
12045 return ffecom_2s (MODIFY_EXPR
, newtype
, lhs
, rhs
);
12048 /* Register source file name. */
12051 ffecom_file (const char *name
)
12053 ffecom_file_ (name
);
12056 /* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
12059 ffecom_notify_init_storage(st);
12061 Gets called when all possible units in an aggregate storage area (a LOCAL
12062 with equivalences or a COMMON) have been initialized. The initialization
12063 info either is in ffestorag_init or, if that is NULL,
12064 ffestorag_accretion:
12066 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12067 even for an array if the array is one element in length!
12069 ffestorag_accretion will contain an opACCTER. It is much like an
12070 opARRTER except it has an ffebit object in it instead of just a size.
12071 The back end can use the info in the ffebit object, if it wants, to
12072 reduce the amount of actual initialization, but in any case it should
12073 kill the ffebit object when done. Also, set accretion to NULL but
12074 init to a non-NULL value.
12076 After performing initialization, DO NOT set init to NULL, because that'll
12077 tell the front end it is ok for more initialization to happen. Instead,
12078 set init to an opANY expression or some such thing that you can use to
12079 tell that you've already initialized the object.
12082 Support two-pass FFE. */
12085 ffecom_notify_init_storage (ffestorag st
)
12087 ffebld init
; /* The initialization expression. */
12089 if (ffestorag_init (st
) == NULL
)
12091 init
= ffestorag_accretion (st
);
12092 assert (init
!= NULL
);
12093 ffestorag_set_accretion (st
, NULL
);
12094 ffestorag_set_accretes (st
, 0);
12095 ffestorag_set_init (st
, init
);
12099 /* ffecom_notify_init_symbol -- A symbol is now fully init'ed
12102 ffecom_notify_init_symbol(s);
12104 Gets called when all possible units in a symbol (not placed in COMMON
12105 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12106 have been initialized. The initialization info either is in
12107 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
12109 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12110 even for an array if the array is one element in length!
12112 ffesymbol_accretion will contain an opACCTER. It is much like an
12113 opARRTER except it has an ffebit object in it instead of just a size.
12114 The back end can use the info in the ffebit object, if it wants, to
12115 reduce the amount of actual initialization, but in any case it should
12116 kill the ffebit object when done. Also, set accretion to NULL but
12117 init to a non-NULL value.
12119 After performing initialization, DO NOT set init to NULL, because that'll
12120 tell the front end it is ok for more initialization to happen. Instead,
12121 set init to an opANY expression or some such thing that you can use to
12122 tell that you've already initialized the object.
12125 Support two-pass FFE. */
12128 ffecom_notify_init_symbol (ffesymbol s
)
12130 ffebld init
; /* The initialization expression. */
12132 if (ffesymbol_storage (s
) == NULL
)
12133 return; /* Do nothing until COMMON/EQUIVALENCE
12134 possibilities checked. */
12136 if ((ffesymbol_init (s
) == NULL
)
12137 && ((init
= ffesymbol_accretion (s
)) != NULL
))
12139 ffesymbol_set_accretion (s
, NULL
);
12140 ffesymbol_set_accretes (s
, 0);
12141 ffesymbol_set_init (s
, init
);
12145 /* ffecom_notify_primary_entry -- Learn which is the primary entry point
12148 ffecom_notify_primary_entry(s);
12150 Gets called when implicit or explicit PROGRAM statement seen or when
12151 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12152 global symbol that serves as the entry point. */
12155 ffecom_notify_primary_entry (ffesymbol s
)
12157 ffecom_primary_entry_
= s
;
12158 ffecom_primary_entry_kind_
= ffesymbol_kind (s
);
12160 if ((ffecom_primary_entry_kind_
== FFEINFO_kindFUNCTION
)
12161 || (ffecom_primary_entry_kind_
== FFEINFO_kindSUBROUTINE
))
12162 ffecom_primary_entry_is_proc_
= TRUE
;
12164 ffecom_primary_entry_is_proc_
= FALSE
;
12166 if (!ffe_is_silent ())
12168 if (ffecom_primary_entry_kind_
== FFEINFO_kindPROGRAM
)
12169 fprintf (stderr
, "%s:\n", ffesymbol_text (s
));
12171 fprintf (stderr
, " %s:\n", ffesymbol_text (s
));
12174 if (ffecom_primary_entry_kind_
== FFEINFO_kindSUBROUTINE
)
12179 for (list
= ffesymbol_dummyargs (s
);
12181 list
= ffebld_trail (list
))
12183 arg
= ffebld_head (list
);
12184 if (ffebld_op (arg
) == FFEBLD_opSTAR
)
12186 ffecom_is_altreturning_
= TRUE
;
12194 ffecom_open_include (char *name
, ffewhereLine l
, ffewhereColumn c
)
12196 return ffecom_open_include_ (name
, l
, c
);
12199 /* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
12202 ffebld expr; // FFE expression.
12203 tree = ffecom_ptr_to_expr(expr);
12205 Like ffecom_expr, but sticks address-of in front of most things. */
12208 ffecom_ptr_to_expr (ffebld expr
)
12211 ffeinfoBasictype bt
;
12212 ffeinfoKindtype kt
;
12215 assert (expr
!= NULL
);
12217 switch (ffebld_op (expr
))
12219 case FFEBLD_opSYMTER
:
12220 s
= ffebld_symter (expr
);
12221 if (ffesymbol_where (s
) == FFEINFO_whereINTRINSIC
)
12225 ix
= ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr
));
12226 assert (ix
!= FFECOM_gfrt
);
12227 if ((item
= ffecom_gfrt_
[ix
]) == NULL_TREE
)
12229 ffecom_make_gfrt_ (ix
);
12230 item
= ffecom_gfrt_
[ix
];
12235 item
= ffesymbol_hook (s
).decl_tree
;
12236 if (item
== NULL_TREE
)
12238 s
= ffecom_sym_transform_ (s
);
12239 item
= ffesymbol_hook (s
).decl_tree
;
12242 assert (item
!= NULL
);
12243 if (item
== error_mark_node
)
12245 if (!ffesymbol_hook (s
).addr
)
12246 item
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (item
)),
12250 case FFEBLD_opARRAYREF
:
12251 return ffecom_arrayref_ (NULL_TREE
, expr
, 1);
12253 case FFEBLD_opCONTER
:
12255 bt
= ffeinfo_basictype (ffebld_info (expr
));
12256 kt
= ffeinfo_kindtype (ffebld_info (expr
));
12258 item
= ffecom_constantunion (&ffebld_constant_union
12259 (ffebld_conter (expr
)), bt
, kt
,
12260 ffecom_tree_type
[bt
][kt
]);
12261 if (item
== error_mark_node
)
12262 return error_mark_node
;
12263 item
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (item
)),
12268 return error_mark_node
;
12271 bt
= ffeinfo_basictype (ffebld_info (expr
));
12272 kt
= ffeinfo_kindtype (ffebld_info (expr
));
12274 item
= ffecom_expr (expr
);
12275 if (item
== error_mark_node
)
12276 return error_mark_node
;
12278 /* The back end currently optimizes a bit too zealously for us, in that
12279 we fail JCB001 if the following block of code is omitted. It checks
12280 to see if the transformed expression is a symbol or array reference,
12281 and encloses it in a SAVE_EXPR if that is the case. */
12284 if ((TREE_CODE (item
) == VAR_DECL
)
12285 || (TREE_CODE (item
) == PARM_DECL
)
12286 || (TREE_CODE (item
) == RESULT_DECL
)
12287 || (TREE_CODE (item
) == INDIRECT_REF
)
12288 || (TREE_CODE (item
) == ARRAY_REF
)
12289 || (TREE_CODE (item
) == COMPONENT_REF
)
12291 || (TREE_CODE (item
) == OFFSET_REF
)
12293 || (TREE_CODE (item
) == BUFFER_REF
)
12294 || (TREE_CODE (item
) == REALPART_EXPR
)
12295 || (TREE_CODE (item
) == IMAGPART_EXPR
))
12297 item
= ffecom_save_tree (item
);
12300 item
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (item
)),
12305 assert ("fall-through error" == NULL
);
12306 return error_mark_node
;
12309 /* Obtain a temp var with given data type.
12311 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12312 or >= 0 for a CHARACTER type.
12314 elements is -1 for a scalar or > 0 for an array of type. */
12317 ffecom_make_tempvar (const char *commentary
, tree type
,
12318 ffetargetCharacterSize size
, int elements
)
12321 static int mynumber
;
12323 assert (current_binding_level
->prep_state
< 2);
12325 if (type
== error_mark_node
)
12326 return error_mark_node
;
12328 if (size
!= FFETARGET_charactersizeNONE
)
12329 type
= build_array_type (type
,
12330 build_range_type (ffecom_f2c_ftnlen_type_node
,
12331 ffecom_f2c_ftnlen_one_node
,
12332 build_int_2 (size
, 0)));
12333 if (elements
!= -1)
12334 type
= build_array_type (type
,
12335 build_range_type (integer_type_node
,
12337 build_int_2 (elements
- 1,
12339 t
= build_decl (VAR_DECL
,
12340 ffecom_get_invented_identifier ("__g77_%s_%d",
12345 t
= start_decl (t
, FALSE
);
12346 finish_decl (t
, NULL_TREE
, FALSE
);
12351 /* Prepare argument pointer to expression.
12353 Like ffecom_prepare_expr, except for expressions to be evaluated
12354 via ffecom_arg_ptr_to_expr. */
12357 ffecom_prepare_arg_ptr_to_expr (ffebld expr
)
12359 /* ~~For now, it seems to be the same thing. */
12360 ffecom_prepare_expr (expr
);
12364 /* End of preparations. */
12367 ffecom_prepare_end (void)
12369 int prep_state
= current_binding_level
->prep_state
;
12371 assert (prep_state
< 2);
12372 current_binding_level
->prep_state
= 2;
12374 return (prep_state
== 1) ? TRUE
: FALSE
;
12377 /* Prepare expression.
12379 This is called before any code is generated for the current block.
12380 It scans the expression, declares any temporaries that might be needed
12381 during evaluation of the expression, and stores those temporaries in
12382 the appropriate "hook" fields of the expression. `dest', if not NULL,
12383 specifies the destination that ffecom_expr_ will see, in case that
12384 helps avoid generating unused temporaries.
12386 ~~Improve to avoid allocating unused temporaries by taking `dest'
12387 into account vis-a-vis aliasing requirements of complex/character
12391 ffecom_prepare_expr_ (ffebld expr
, ffebld dest UNUSED
)
12393 ffeinfoBasictype bt
;
12394 ffeinfoKindtype kt
;
12395 ffetargetCharacterSize sz
;
12396 tree tempvar
= NULL_TREE
;
12398 assert (current_binding_level
->prep_state
< 2);
12403 bt
= ffeinfo_basictype (ffebld_info (expr
));
12404 kt
= ffeinfo_kindtype (ffebld_info (expr
));
12405 sz
= ffeinfo_size (ffebld_info (expr
));
12407 /* Generate whatever temporaries are needed to represent the result
12408 of the expression. */
12410 if (bt
== FFEINFO_basictypeCHARACTER
)
12412 while (ffebld_op (expr
) == FFEBLD_opPAREN
)
12413 expr
= ffebld_left (expr
);
12416 switch (ffebld_op (expr
))
12419 /* Don't make temps for SYMTER, CONTER, etc. */
12420 if (ffebld_arity (expr
) == 0)
12425 case FFEINFO_basictypeCOMPLEX
:
12426 if (ffebld_op (expr
) == FFEBLD_opFUNCREF
)
12430 if (ffebld_op (ffebld_left (expr
)) != FFEBLD_opSYMTER
)
12433 s
= ffebld_symter (ffebld_left (expr
));
12434 if (ffesymbol_where (s
) == FFEINFO_whereCONSTANT
12435 || (ffesymbol_where (s
) != FFEINFO_whereINTRINSIC
12436 && ! ffesymbol_is_f2c (s
))
12437 || (ffesymbol_where (s
) == FFEINFO_whereINTRINSIC
12438 && ! ffe_is_f2c_library ()))
12441 else if (ffebld_op (expr
) == FFEBLD_opPOWER
)
12443 /* Requires special treatment. There's no POW_CC function
12444 in libg2c, so POW_ZZ is used, which means we always
12445 need a double-complex temp, not a single-complex. */
12446 kt
= FFEINFO_kindtypeREAL2
;
12448 else if (ffebld_op (expr
) != FFEBLD_opDIVIDE
)
12449 /* The other ops don't need temps for complex operands. */
12452 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12453 REAL(C). See 19990325-0.f, routine `check', for cases. */
12454 tempvar
= ffecom_make_tempvar ("complex",
12456 [FFEINFO_basictypeCOMPLEX
][kt
],
12457 FFETARGET_charactersizeNONE
,
12461 case FFEINFO_basictypeCHARACTER
:
12462 if (ffebld_op (expr
) != FFEBLD_opFUNCREF
)
12465 if (sz
== FFETARGET_charactersizeNONE
)
12466 /* ~~Kludge alert! This should someday be fixed. */
12469 tempvar
= ffecom_make_tempvar ("char", char_type_node
, sz
, -1);
12477 case FFEBLD_opCONCATENATE
:
12479 /* This gets special handling, because only one set of temps
12480 is needed for a tree of these -- the tree is treated as
12481 a flattened list of concatenations when generating code. */
12483 ffecomConcatList_ catlist
;
12484 tree ltmp
, itmp
, result
;
12488 catlist
= ffecom_concat_list_new_ (expr
, FFETARGET_charactersizeNONE
);
12489 count
= ffecom_concat_list_count_ (catlist
);
12494 = ffecom_make_tempvar ("concat_len",
12495 ffecom_f2c_ftnlen_type_node
,
12496 FFETARGET_charactersizeNONE
, count
);
12498 = ffecom_make_tempvar ("concat_item",
12499 ffecom_f2c_address_type_node
,
12500 FFETARGET_charactersizeNONE
, count
);
12502 = ffecom_make_tempvar ("concat_res",
12504 ffecom_concat_list_maxlen_ (catlist
),
12507 tempvar
= make_tree_vec (3);
12508 TREE_VEC_ELT (tempvar
, 0) = ltmp
;
12509 TREE_VEC_ELT (tempvar
, 1) = itmp
;
12510 TREE_VEC_ELT (tempvar
, 2) = result
;
12513 for (i
= 0; i
< count
; ++i
)
12514 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist
,
12517 ffecom_concat_list_kill_ (catlist
);
12521 ffebld_nonter_set_hook (expr
, tempvar
);
12522 current_binding_level
->prep_state
= 1;
12527 case FFEBLD_opCONVERT
:
12528 if (bt
== FFEINFO_basictypeCHARACTER
12529 && ((ffebld_size_known (ffebld_left (expr
))
12530 == FFETARGET_charactersizeNONE
)
12531 || (ffebld_size_known (ffebld_left (expr
)) >= sz
)))
12532 tempvar
= ffecom_make_tempvar ("convert", char_type_node
, sz
, -1);
12538 ffebld_nonter_set_hook (expr
, tempvar
);
12539 current_binding_level
->prep_state
= 1;
12542 /* Prepare subexpressions for this expr. */
12544 switch (ffebld_op (expr
))
12546 case FFEBLD_opPERCENT_LOC
:
12547 ffecom_prepare_ptr_to_expr (ffebld_left (expr
));
12550 case FFEBLD_opPERCENT_VAL
:
12551 case FFEBLD_opPERCENT_REF
:
12552 ffecom_prepare_expr (ffebld_left (expr
));
12555 case FFEBLD_opPERCENT_DESCR
:
12556 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr
));
12559 case FFEBLD_opITEM
:
12565 item
= ffebld_trail (item
))
12566 if (ffebld_head (item
) != NULL
)
12567 ffecom_prepare_expr (ffebld_head (item
));
12572 /* Need to handle character conversion specially. */
12573 switch (ffebld_arity (expr
))
12576 ffecom_prepare_expr (ffebld_left (expr
));
12577 ffecom_prepare_expr (ffebld_right (expr
));
12581 ffecom_prepare_expr (ffebld_left (expr
));
12592 /* Prepare expression for reading and writing.
12594 Like ffecom_prepare_expr, except for expressions to be evaluated
12595 via ffecom_expr_rw. */
12598 ffecom_prepare_expr_rw (tree type
, ffebld expr
)
12600 /* This is all we support for now. */
12601 assert (type
== NULL_TREE
|| type
== ffecom_type_expr (expr
));
12603 /* ~~For now, it seems to be the same thing. */
12604 ffecom_prepare_expr (expr
);
12608 /* Prepare expression for writing.
12610 Like ffecom_prepare_expr, except for expressions to be evaluated
12611 via ffecom_expr_w. */
12614 ffecom_prepare_expr_w (tree type
, ffebld expr
)
12616 /* This is all we support for now. */
12617 assert (type
== NULL_TREE
|| type
== ffecom_type_expr (expr
));
12619 /* ~~For now, it seems to be the same thing. */
12620 ffecom_prepare_expr (expr
);
12624 /* Prepare expression for returning.
12626 Like ffecom_prepare_expr, except for expressions to be evaluated
12627 via ffecom_return_expr. */
12630 ffecom_prepare_return_expr (ffebld expr
)
12632 assert (current_binding_level
->prep_state
< 2);
12634 if (ffecom_primary_entry_kind_
== FFEINFO_kindSUBROUTINE
12635 && ffecom_is_altreturning_
12637 ffecom_prepare_expr (expr
);
12640 /* Prepare pointer to expression.
12642 Like ffecom_prepare_expr, except for expressions to be evaluated
12643 via ffecom_ptr_to_expr. */
12646 ffecom_prepare_ptr_to_expr (ffebld expr
)
12648 /* ~~For now, it seems to be the same thing. */
12649 ffecom_prepare_expr (expr
);
12653 /* Transform expression into constant pointer-to-expression tree.
12655 If the expression can be transformed into a pointer-to-expression tree
12656 that is constant, that is done, and the tree returned. Else NULL_TREE
12659 That way, a caller can attempt to provide compile-time initialization
12660 of a variable and, if that fails, *then* choose to start a new block
12661 and resort to using temporaries, as appropriate. */
12664 ffecom_ptr_to_const_expr (ffebld expr
)
12667 return integer_zero_node
;
12669 if (ffebld_op (expr
) == FFEBLD_opANY
)
12670 return error_mark_node
;
12672 if (ffebld_arity (expr
) == 0
12673 && (ffebld_op (expr
) != FFEBLD_opSYMTER
12674 || ffebld_where (expr
) == FFEINFO_whereCOMMON
12675 || ffebld_where (expr
) == FFEINFO_whereGLOBAL
12676 || ffebld_where (expr
) == FFEINFO_whereINTRINSIC
))
12680 t
= ffecom_ptr_to_expr (expr
);
12681 assert (TREE_CONSTANT (t
));
12688 /* ffecom_return_expr -- Returns return-value expr given alt return expr
12690 tree rtn; // NULL_TREE means use expand_null_return()
12691 ffebld expr; // NULL if no alt return expr to RETURN stmt
12692 rtn = ffecom_return_expr(expr);
12694 Based on the program unit type and other info (like return function
12695 type, return master function type when alternate ENTRY points,
12696 whether subroutine has any alternate RETURN points, etc), returns the
12697 appropriate expression to be returned to the caller, or NULL_TREE
12698 meaning no return value or the caller expects it to be returned somewhere
12699 else (which is handled by other parts of this module). */
12702 ffecom_return_expr (ffebld expr
)
12706 switch (ffecom_primary_entry_kind_
)
12708 case FFEINFO_kindPROGRAM
:
12709 case FFEINFO_kindBLOCKDATA
:
12713 case FFEINFO_kindSUBROUTINE
:
12714 if (!ffecom_is_altreturning_
)
12715 rtn
= NULL_TREE
; /* No alt returns, never an expr. */
12716 else if (expr
== NULL
)
12717 rtn
= integer_zero_node
;
12719 rtn
= ffecom_expr (expr
);
12722 case FFEINFO_kindFUNCTION
:
12723 if ((ffecom_multi_retval_
!= NULL_TREE
)
12724 || (ffesymbol_basictype (ffecom_primary_entry_
)
12725 == FFEINFO_basictypeCHARACTER
)
12726 || ((ffesymbol_basictype (ffecom_primary_entry_
)
12727 == FFEINFO_basictypeCOMPLEX
)
12728 && (ffecom_num_entrypoints_
== 0)
12729 && ffesymbol_is_f2c (ffecom_primary_entry_
)))
12730 { /* Value is returned by direct assignment
12731 into (implicit) dummy. */
12735 rtn
= ffecom_func_result_
;
12737 /* Spurious error if RETURN happens before first reference! So elide
12738 this code. In particular, for debugging registry, rtn should always
12739 be non-null after all, but TREE_USED won't be set until we encounter
12740 a reference in the code. Perfectly okay (but weird) code that,
12741 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
12742 this diagnostic for no reason. Have people use -O -Wuninitialized
12743 and leave it to the back end to find obviously weird cases. */
12745 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
12746 situation; if the return value has never been referenced, it won't
12747 have a tree under 2pass mode. */
12748 if ((rtn
== NULL_TREE
)
12749 || !TREE_USED (rtn
))
12751 ffebad_start (FFEBAD_RETURN_VALUE_UNSET
);
12752 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_
),
12753 ffesymbol_where_column (ffecom_primary_entry_
));
12754 ffebad_string (ffesymbol_text (ffesymbol_funcresult
12755 (ffecom_primary_entry_
)));
12762 assert ("bad unit kind" == NULL
);
12763 case FFEINFO_kindANY
:
12764 rtn
= error_mark_node
;
12771 /* Do save_expr only if tree is not error_mark_node. */
12774 ffecom_save_tree (tree t
)
12776 return save_expr (t
);
12779 /* Start a compound statement (block). */
12782 ffecom_start_compstmt (void)
12784 bison_rule_pushlevel_ ();
12787 /* Public entry point for front end to access start_decl. */
12790 ffecom_start_decl (tree decl
, bool is_initialized
)
12792 DECL_INITIAL (decl
) = is_initialized
? error_mark_node
: NULL_TREE
;
12793 return start_decl (decl
, FALSE
);
12796 /* ffecom_sym_commit -- Symbol's state being committed to reality
12799 ffecom_sym_commit(s);
12801 Does whatever the backend needs when a symbol is committed after having
12802 been backtrackable for a period of time. */
12805 ffecom_sym_commit (ffesymbol s UNUSED
)
12807 assert (!ffesymbol_retractable ());
12810 /* ffecom_sym_end_transition -- Perform end transition on all symbols
12812 ffecom_sym_end_transition();
12814 Does backend-specific stuff and also calls ffest_sym_end_transition
12815 to do the necessary FFE stuff.
12817 Backtracking is never enabled when this fn is called, so don't worry
12821 ffecom_sym_end_transition (ffesymbol s
)
12825 assert (!ffesymbol_retractable ());
12827 s
= ffest_sym_end_transition (s
);
12829 if ((ffesymbol_kind (s
) == FFEINFO_kindBLOCKDATA
)
12830 && (ffesymbol_where (s
) == FFEINFO_whereGLOBAL
))
12832 ffecom_list_blockdata_
12833 = ffebld_new_item (ffebld_new_symter (s
, FFEINTRIN_genNONE
,
12834 FFEINTRIN_specNONE
,
12835 FFEINTRIN_impNONE
),
12836 ffecom_list_blockdata_
);
12839 /* This is where we finally notice that a symbol has partial initialization
12840 and finalize it. */
12842 if (ffesymbol_accretion (s
) != NULL
)
12844 assert (ffesymbol_init (s
) == NULL
);
12845 ffecom_notify_init_symbol (s
);
12847 else if (((st
= ffesymbol_storage (s
)) != NULL
)
12848 && ((st
= ffestorag_parent (st
)) != NULL
)
12849 && (ffestorag_accretion (st
) != NULL
))
12851 assert (ffestorag_init (st
) == NULL
);
12852 ffecom_notify_init_storage (st
);
12855 if ((ffesymbol_kind (s
) == FFEINFO_kindCOMMON
)
12856 && (ffesymbol_where (s
) == FFEINFO_whereLOCAL
)
12857 && (ffesymbol_storage (s
) != NULL
))
12859 ffecom_list_common_
12860 = ffebld_new_item (ffebld_new_symter (s
, FFEINTRIN_genNONE
,
12861 FFEINTRIN_specNONE
,
12862 FFEINTRIN_impNONE
),
12863 ffecom_list_common_
);
12869 /* ffecom_sym_exec_transition -- Perform exec transition on all symbols
12871 ffecom_sym_exec_transition();
12873 Does backend-specific stuff and also calls ffest_sym_exec_transition
12874 to do the necessary FFE stuff.
12876 See the long-winded description in ffecom_sym_learned for info
12877 on handling the situation where backtracking is inhibited. */
12880 ffecom_sym_exec_transition (ffesymbol s
)
12882 s
= ffest_sym_exec_transition (s
);
12887 /* ffecom_sym_learned -- Initial or more info gained on symbol after exec
12890 s = ffecom_sym_learned(s);
12892 Called when a new symbol is seen after the exec transition or when more
12893 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
12894 it arrives here is that all its latest info is updated already, so its
12895 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
12896 field filled in if its gone through here or exec_transition first, and
12899 The backend probably wants to check ffesymbol_retractable() to see if
12900 backtracking is in effect. If so, the FFE's changes to the symbol may
12901 be retracted (undone) or committed (ratified), at which time the
12902 appropriate ffecom_sym_retract or _commit function will be called
12905 If the backend has its own backtracking mechanism, great, use it so that
12906 committal is a simple operation. Though it doesn't make much difference,
12907 I suppose: the reason for tentative symbol evolution in the FFE is to
12908 enable error detection in weird incorrect statements early and to disable
12909 incorrect error detection on a correct statement. The backend is not
12910 likely to introduce any information that'll get involved in these
12911 considerations, so it is probably just fine that the implementation
12912 model for this fn and for _exec_transition is to not do anything
12913 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
12914 and instead wait until ffecom_sym_commit is called (which it never
12915 will be as long as we're using ambiguity-detecting statement analysis in
12916 the FFE, which we are initially to shake out the code, but don't depend
12917 on this), otherwise go ahead and do whatever is needed.
12919 In essence, then, when this fn and _exec_transition get called while
12920 backtracking is enabled, a general mechanism would be to flag which (or
12921 both) of these were called (and in what order? neat question as to what
12922 might happen that I'm too lame to think through right now) and then when
12923 _commit is called reproduce the original calling sequence, if any, for
12924 the two fns (at which point backtracking will, of course, be disabled). */
12927 ffecom_sym_learned (ffesymbol s
)
12929 ffestorag_exec_layout (s
);
12934 /* ffecom_sym_retract -- Symbol's state being retracted from reality
12937 ffecom_sym_retract(s);
12939 Does whatever the backend needs when a symbol is retracted after having
12940 been backtrackable for a period of time. */
12943 ffecom_sym_retract (ffesymbol s UNUSED
)
12945 assert (!ffesymbol_retractable ());
12947 #if 0 /* GCC doesn't commit any backtrackable sins,
12948 so nothing needed here. */
12949 switch (ffesymbol_hook (s
).state
)
12951 case 0: /* nothing happened yet. */
12954 case 1: /* exec transition happened. */
12957 case 2: /* learned happened. */
12960 case 3: /* learned then exec. */
12963 case 4: /* exec then learned. */
12967 assert ("bad hook state" == NULL
);
12973 /* Create temporary gcc label. */
12976 ffecom_temp_label (void)
12979 static int mynumber
= 0;
12981 glabel
= build_decl (LABEL_DECL
,
12982 ffecom_get_invented_identifier ("__g77_label_%d",
12985 DECL_CONTEXT (glabel
) = current_function_decl
;
12986 DECL_MODE (glabel
) = VOIDmode
;
12991 /* Return an expression that is usable as an arg in a conditional context
12992 (IF, DO WHILE, .NOT., and so on).
12994 Use the one provided for the back end as of >2.6.0. */
12997 ffecom_truth_value (tree expr
)
12999 return ffe_truthvalue_conversion (expr
);
13002 /* Return the inversion of a truth value (the inversion of what
13003 ffecom_truth_value builds).
13005 Apparently invert_truthvalue, which is properly in the back end, is
13006 enough for now, so just use it. */
13009 ffecom_truth_value_invert (tree expr
)
13011 return invert_truthvalue (ffecom_truth_value (expr
));
13014 /* Return the tree that is the type of the expression, as would be
13015 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13016 transforming the expression, generating temporaries, etc. */
13019 ffecom_type_expr (ffebld expr
)
13021 ffeinfoBasictype bt
;
13022 ffeinfoKindtype kt
;
13025 assert (expr
!= NULL
);
13027 bt
= ffeinfo_basictype (ffebld_info (expr
));
13028 kt
= ffeinfo_kindtype (ffebld_info (expr
));
13029 tree_type
= ffecom_tree_type
[bt
][kt
];
13031 switch (ffebld_op (expr
))
13033 case FFEBLD_opCONTER
:
13034 case FFEBLD_opSYMTER
:
13035 case FFEBLD_opARRAYREF
:
13036 case FFEBLD_opUPLUS
:
13037 case FFEBLD_opPAREN
:
13038 case FFEBLD_opUMINUS
:
13040 case FFEBLD_opSUBTRACT
:
13041 case FFEBLD_opMULTIPLY
:
13042 case FFEBLD_opDIVIDE
:
13043 case FFEBLD_opPOWER
:
13045 case FFEBLD_opFUNCREF
:
13046 case FFEBLD_opSUBRREF
:
13050 case FFEBLD_opNEQV
:
13052 case FFEBLD_opCONVERT
:
13059 case FFEBLD_opPERCENT_LOC
:
13062 case FFEBLD_opACCTER
:
13063 case FFEBLD_opARRTER
:
13064 case FFEBLD_opITEM
:
13065 case FFEBLD_opSTAR
:
13066 case FFEBLD_opBOUNDS
:
13067 case FFEBLD_opREPEAT
:
13068 case FFEBLD_opLABTER
:
13069 case FFEBLD_opLABTOK
:
13070 case FFEBLD_opIMPDO
:
13071 case FFEBLD_opCONCATENATE
:
13072 case FFEBLD_opSUBSTR
:
13074 assert ("bad op for ffecom_type_expr" == NULL
);
13075 /* Fall through. */
13077 return error_mark_node
;
13081 /* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13083 If the PARM_DECL already exists, return it, else create it. It's an
13084 integer_type_node argument for the master function that implements a
13085 subroutine or function with more than one entrypoint and is bound at
13086 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13087 first ENTRY statement, and so on). */
13090 ffecom_which_entrypoint_decl (void)
13092 assert (ffecom_which_entrypoint_decl_
!= NULL_TREE
);
13094 return ffecom_which_entrypoint_decl_
;
13097 /* The following sections consists of private and public functions
13098 that have the same names and perform roughly the same functions
13099 as counterparts in the C front end. Changes in the C front end
13100 might affect how things should be done here. Only functions
13101 needed by the back end should be public here; the rest should
13102 be private (static in the C sense). Functions needed by other
13103 g77 front-end modules should be accessed by them via public
13104 ffecom_* names, which should themselves call private versions
13105 in this section so the private versions are easy to recognize
13106 when upgrading to a new gcc and finding interesting changes
13109 Functions named after rule "foo:" in c-parse.y are named
13110 "bison_rule_foo_" so they are easy to find. */
13113 bison_rule_pushlevel_ (void)
13115 emit_line_note (input_location
);
13117 clear_last_expr ();
13118 expand_start_bindings (0);
13122 bison_rule_compstmt_ (void)
13125 int keep
= kept_level_p ();
13127 /* Make the temps go away. */
13129 current_binding_level
->names
= NULL_TREE
;
13131 emit_line_note (input_location
);
13132 expand_end_bindings (getdecls (), keep
, 0);
13133 t
= poplevel (keep
, 1, 0);
13138 /* Return a definition for a builtin function named NAME and whose data type
13139 is TYPE. TYPE should be a function type with argument types.
13140 FUNCTION_CODE tells later passes how to compile calls to this function.
13141 See tree.h for its possible values.
13143 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13144 the name to be called if we can't opencode the function. If
13145 ATTRS is nonzero, use that for the function's attribute list. */
13148 builtin_function (const char *name
, tree type
, int function_code
,
13149 enum built_in_class
class, const char *library_name
,
13150 tree attrs ATTRIBUTE_UNUSED
)
13152 tree decl
= build_decl (FUNCTION_DECL
, get_identifier (name
), type
);
13153 DECL_EXTERNAL (decl
) = 1;
13154 TREE_PUBLIC (decl
) = 1;
13156 SET_DECL_ASSEMBLER_NAME (decl
, get_identifier (library_name
));
13157 make_decl_rtl (decl
, NULL
);
13159 DECL_BUILT_IN_CLASS (decl
) = class;
13160 DECL_FUNCTION_CODE (decl
) = function_code
;
13165 /* Handle when a new declaration NEWDECL
13166 has the same name as an old one OLDDECL
13167 in the same binding contour.
13168 Prints an error message if appropriate.
13170 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13171 Otherwise, return 0. */
13174 duplicate_decls (tree newdecl
, tree olddecl
)
13176 int types_match
= 1;
13177 int new_is_definition
= (TREE_CODE (newdecl
) == FUNCTION_DECL
13178 && DECL_INITIAL (newdecl
) != 0);
13179 tree oldtype
= TREE_TYPE (olddecl
);
13180 tree newtype
= TREE_TYPE (newdecl
);
13182 if (olddecl
== newdecl
)
13185 if (TREE_CODE (newtype
) == ERROR_MARK
13186 || TREE_CODE (oldtype
) == ERROR_MARK
)
13189 /* New decl is completely inconsistent with the old one =>
13190 tell caller to replace the old one.
13191 This is always an error except in the case of shadowing a builtin. */
13192 if (TREE_CODE (olddecl
) != TREE_CODE (newdecl
))
13195 /* For real parm decl following a forward decl,
13196 return 1 so old decl will be reused. */
13197 if (types_match
&& TREE_CODE (newdecl
) == PARM_DECL
13198 && TREE_ASM_WRITTEN (olddecl
) && ! TREE_ASM_WRITTEN (newdecl
))
13201 /* The new declaration is the same kind of object as the old one.
13202 The declarations may partially match. Print warnings if they don't
13203 match enough. Ultimately, copy most of the information from the new
13204 decl to the old one, and keep using the old one. */
13206 if (TREE_CODE (olddecl
) == FUNCTION_DECL
13207 && DECL_BUILT_IN (olddecl
))
13209 /* A function declaration for a built-in function. */
13210 if (!TREE_PUBLIC (newdecl
))
13212 else if (!types_match
)
13214 /* Accept the return type of the new declaration if same modes. */
13215 tree oldreturntype
= TREE_TYPE (TREE_TYPE (olddecl
));
13216 tree newreturntype
= TREE_TYPE (TREE_TYPE (newdecl
));
13218 if (TYPE_MODE (oldreturntype
) == TYPE_MODE (newreturntype
))
13220 /* Function types may be shared, so we can't just modify
13221 the return type of olddecl's function type. */
13223 = build_function_type (newreturntype
,
13224 TYPE_ARG_TYPES (TREE_TYPE (olddecl
)));
13228 TREE_TYPE (olddecl
) = newtype
;
13234 else if (TREE_CODE (olddecl
) == FUNCTION_DECL
13235 && DECL_SOURCE_LINE (olddecl
) == 0)
13237 /* A function declaration for a predeclared function
13238 that isn't actually built in. */
13239 if (!TREE_PUBLIC (newdecl
))
13241 else if (!types_match
)
13243 /* If the types don't match, preserve volatility indication.
13244 Later on, we will discard everything else about the
13245 default declaration. */
13246 TREE_THIS_VOLATILE (newdecl
) |= TREE_THIS_VOLATILE (olddecl
);
13250 /* Copy all the DECL_... slots specified in the new decl
13251 except for any that we copy here from the old type.
13253 Past this point, we don't change OLDTYPE and NEWTYPE
13254 even if we change the types of NEWDECL and OLDDECL. */
13258 /* Merge the data types specified in the two decls. */
13259 if (TREE_CODE (newdecl
) != FUNCTION_DECL
|| !DECL_BUILT_IN (olddecl
))
13260 TREE_TYPE (newdecl
)
13261 = TREE_TYPE (olddecl
)
13262 = TREE_TYPE (newdecl
);
13264 /* Lay the type out, unless already done. */
13265 if (oldtype
!= TREE_TYPE (newdecl
))
13267 if (TREE_TYPE (newdecl
) != error_mark_node
)
13268 layout_type (TREE_TYPE (newdecl
));
13269 if (TREE_CODE (newdecl
) != FUNCTION_DECL
13270 && TREE_CODE (newdecl
) != TYPE_DECL
13271 && TREE_CODE (newdecl
) != CONST_DECL
)
13272 layout_decl (newdecl
, 0);
13276 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13277 DECL_SIZE (newdecl
) = DECL_SIZE (olddecl
);
13278 DECL_SIZE_UNIT (newdecl
) = DECL_SIZE_UNIT (olddecl
);
13279 if (TREE_CODE (olddecl
) != FUNCTION_DECL
)
13280 if (DECL_ALIGN (olddecl
) > DECL_ALIGN (newdecl
))
13282 DECL_ALIGN (newdecl
) = DECL_ALIGN (olddecl
);
13283 DECL_USER_ALIGN (newdecl
) |= DECL_USER_ALIGN (olddecl
);
13287 /* Keep the old rtl since we can safely use it. */
13288 COPY_DECL_RTL (olddecl
, newdecl
);
13290 /* Merge the type qualifiers. */
13291 if (TREE_READONLY (newdecl
))
13292 TREE_READONLY (olddecl
) = 1;
13293 if (TREE_THIS_VOLATILE (newdecl
))
13295 TREE_THIS_VOLATILE (olddecl
) = 1;
13296 if (TREE_CODE (newdecl
) == VAR_DECL
)
13297 make_var_volatile (newdecl
);
13300 /* Keep source location of definition rather than declaration.
13301 Likewise, keep decl at outer scope. */
13302 if ((DECL_INITIAL (newdecl
) == 0 && DECL_INITIAL (olddecl
) != 0)
13303 || (DECL_CONTEXT (newdecl
) != 0 && DECL_CONTEXT (olddecl
) == 0))
13305 DECL_SOURCE_LOCATION (newdecl
) = DECL_SOURCE_LOCATION (olddecl
);
13307 if (DECL_CONTEXT (olddecl
) == 0
13308 && TREE_CODE (newdecl
) != FUNCTION_DECL
)
13309 DECL_CONTEXT (newdecl
) = 0;
13312 /* Merge the unused-warning information. */
13313 if (DECL_IN_SYSTEM_HEADER (olddecl
))
13314 DECL_IN_SYSTEM_HEADER (newdecl
) = 1;
13315 else if (DECL_IN_SYSTEM_HEADER (newdecl
))
13316 DECL_IN_SYSTEM_HEADER (olddecl
) = 1;
13318 /* Merge the initialization information. */
13319 if (DECL_INITIAL (newdecl
) == 0)
13320 DECL_INITIAL (newdecl
) = DECL_INITIAL (olddecl
);
13322 /* Merge the section attribute.
13323 We want to issue an error if the sections conflict but that must be
13324 done later in decl_attributes since we are called before attributes
13326 if (DECL_SECTION_NAME (newdecl
) == NULL_TREE
)
13327 DECL_SECTION_NAME (newdecl
) = DECL_SECTION_NAME (olddecl
);
13329 /* Copy the assembler name. */
13330 COPY_DECL_ASSEMBLER_NAME (olddecl
, newdecl
);
13332 if (TREE_CODE (newdecl
) == FUNCTION_DECL
)
13334 DECL_STATIC_CONSTRUCTOR(newdecl
) |= DECL_STATIC_CONSTRUCTOR(olddecl
);
13335 DECL_STATIC_DESTRUCTOR (newdecl
) |= DECL_STATIC_DESTRUCTOR (olddecl
);
13336 TREE_THIS_VOLATILE (newdecl
) |= TREE_THIS_VOLATILE (olddecl
);
13337 TREE_READONLY (newdecl
) |= TREE_READONLY (olddecl
);
13338 DECL_IS_MALLOC (newdecl
) |= DECL_IS_MALLOC (olddecl
);
13339 DECL_IS_PURE (newdecl
) |= DECL_IS_PURE (olddecl
);
13342 /* If cannot merge, then use the new type and qualifiers,
13343 and don't preserve the old rtl. */
13346 TREE_TYPE (olddecl
) = TREE_TYPE (newdecl
);
13347 TREE_READONLY (olddecl
) = TREE_READONLY (newdecl
);
13348 TREE_THIS_VOLATILE (olddecl
) = TREE_THIS_VOLATILE (newdecl
);
13349 TREE_SIDE_EFFECTS (olddecl
) = TREE_SIDE_EFFECTS (newdecl
);
13352 /* Merge the storage class information. */
13353 /* For functions, static overrides non-static. */
13354 if (TREE_CODE (newdecl
) == FUNCTION_DECL
)
13356 TREE_PUBLIC (newdecl
) &= TREE_PUBLIC (olddecl
);
13357 /* This is since we don't automatically
13358 copy the attributes of NEWDECL into OLDDECL. */
13359 TREE_PUBLIC (olddecl
) = TREE_PUBLIC (newdecl
);
13360 /* If this clears `static', clear it in the identifier too. */
13361 if (! TREE_PUBLIC (olddecl
))
13362 TREE_PUBLIC (DECL_NAME (olddecl
)) = 0;
13364 if (DECL_EXTERNAL (newdecl
))
13366 TREE_STATIC (newdecl
) = TREE_STATIC (olddecl
);
13367 DECL_EXTERNAL (newdecl
) = DECL_EXTERNAL (olddecl
);
13368 /* An extern decl does not override previous storage class. */
13369 TREE_PUBLIC (newdecl
) = TREE_PUBLIC (olddecl
);
13373 TREE_STATIC (olddecl
) = TREE_STATIC (newdecl
);
13374 TREE_PUBLIC (olddecl
) = TREE_PUBLIC (newdecl
);
13377 /* If either decl says `inline', this fn is inline,
13378 unless its definition was passed already. */
13379 if (DECL_INLINE (newdecl
) && DECL_INITIAL (olddecl
) == 0)
13380 DECL_INLINE (olddecl
) = 1;
13381 DECL_INLINE (newdecl
) = DECL_INLINE (olddecl
);
13383 /* Get rid of any built-in function if new arg types don't match it
13384 or if we have a function definition. */
13385 if (TREE_CODE (newdecl
) == FUNCTION_DECL
13386 && DECL_BUILT_IN (olddecl
)
13387 && (!types_match
|| new_is_definition
))
13389 TREE_TYPE (olddecl
) = TREE_TYPE (newdecl
);
13390 DECL_BUILT_IN_CLASS (olddecl
) = NOT_BUILT_IN
;
13393 /* If redeclaring a builtin function, and not a definition,
13395 Also preserve various other info from the definition. */
13396 if (TREE_CODE (newdecl
) == FUNCTION_DECL
&& !new_is_definition
)
13398 if (DECL_BUILT_IN (olddecl
))
13400 DECL_BUILT_IN_CLASS (newdecl
) = DECL_BUILT_IN_CLASS (olddecl
);
13401 DECL_FUNCTION_CODE (newdecl
) = DECL_FUNCTION_CODE (olddecl
);
13404 DECL_RESULT (newdecl
) = DECL_RESULT (olddecl
);
13405 DECL_INITIAL (newdecl
) = DECL_INITIAL (olddecl
);
13406 DECL_STRUCT_FUNCTION (newdecl
) = DECL_STRUCT_FUNCTION (olddecl
);
13407 DECL_ARGUMENTS (newdecl
) = DECL_ARGUMENTS (olddecl
);
13410 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13411 But preserve olddecl's DECL_UID. */
13413 register unsigned olddecl_uid
= DECL_UID (olddecl
);
13415 memcpy ((char *) olddecl
+ sizeof (struct tree_common
),
13416 (char *) newdecl
+ sizeof (struct tree_common
),
13417 sizeof (struct tree_decl
) - sizeof (struct tree_common
));
13418 DECL_UID (olddecl
) = olddecl_uid
;
13424 /* Finish processing of a declaration;
13425 install its initial value.
13426 If the length of an array type is not known before,
13427 it must be determined now, from the initial value, or it is an error. */
13430 finish_decl (tree decl
, tree init
, bool is_top_level
)
13432 register tree type
= TREE_TYPE (decl
);
13433 int was_incomplete
= (DECL_SIZE (decl
) == 0);
13434 bool at_top_level
= (current_binding_level
== global_binding_level
);
13435 bool top_level
= is_top_level
|| at_top_level
;
13437 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13439 assert (!is_top_level
|| !at_top_level
);
13441 if (TREE_CODE (decl
) == PARM_DECL
)
13442 assert (init
== NULL_TREE
);
13443 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
13444 overlaps DECL_ARG_TYPE. */
13445 else if (init
== NULL_TREE
)
13446 assert (DECL_INITIAL (decl
) == NULL_TREE
);
13448 assert (DECL_INITIAL (decl
) == error_mark_node
);
13450 if (init
!= NULL_TREE
)
13452 if (TREE_CODE (decl
) != TYPE_DECL
)
13453 DECL_INITIAL (decl
) = init
;
13456 /* typedef foo = bar; store the type of bar as the type of foo. */
13457 TREE_TYPE (decl
) = TREE_TYPE (init
);
13458 DECL_INITIAL (decl
) = init
= 0;
13462 /* Deduce size of array from initialization, if not already known */
13464 if (TREE_CODE (type
) == ARRAY_TYPE
13465 && TYPE_DOMAIN (type
) == 0
13466 && TREE_CODE (decl
) != TYPE_DECL
)
13468 assert (top_level
);
13469 assert (was_incomplete
);
13471 layout_decl (decl
, 0);
13474 if (TREE_CODE (decl
) == VAR_DECL
)
13476 if (DECL_SIZE (decl
) == NULL_TREE
13477 && TYPE_SIZE (TREE_TYPE (decl
)) != NULL_TREE
)
13478 layout_decl (decl
, 0);
13480 if (DECL_SIZE (decl
) == NULL_TREE
13481 && (TREE_STATIC (decl
)
13483 /* A static variable with an incomplete type is an error if it is
13484 initialized. Also if it is not file scope. Otherwise, let it
13485 through, but if it is not `extern' then it may cause an error
13487 (DECL_INITIAL (decl
) != 0 || DECL_CONTEXT (decl
) != 0)
13489 /* An automatic variable with an incomplete type is an error. */
13490 !DECL_EXTERNAL (decl
)))
13492 assert ("storage size not known" == NULL
);
13496 if ((DECL_EXTERNAL (decl
) || TREE_STATIC (decl
))
13497 && (DECL_SIZE (decl
) != 0)
13498 && (TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
))
13500 assert ("storage size not constant" == NULL
);
13505 /* Output the assembler code and/or RTL code for variables and functions,
13506 unless the type is an undefined structure or union. If not, it will get
13507 done when the type is completed. */
13509 if (TREE_CODE (decl
) == VAR_DECL
|| TREE_CODE (decl
) == FUNCTION_DECL
)
13511 rest_of_decl_compilation (decl
, NULL
,
13512 DECL_CONTEXT (decl
) == 0,
13515 if (DECL_CONTEXT (decl
) != 0)
13517 /* Recompute the RTL of a local array now if it used to be an
13518 incomplete type. */
13520 && !TREE_STATIC (decl
) && !DECL_EXTERNAL (decl
))
13522 /* If we used it already as memory, it must stay in memory. */
13523 TREE_ADDRESSABLE (decl
) = TREE_USED (decl
);
13524 /* If it's still incomplete now, no init will save it. */
13525 if (DECL_SIZE (decl
) == 0)
13526 DECL_INITIAL (decl
) = 0;
13527 expand_decl (decl
);
13529 /* Compute and store the initial value. */
13530 if (TREE_CODE (decl
) != FUNCTION_DECL
)
13531 expand_decl_init (decl
);
13534 else if (TREE_CODE (decl
) == TYPE_DECL
)
13536 rest_of_decl_compilation (decl
, NULL
,
13537 DECL_CONTEXT (decl
) == 0,
13541 /* At the end of a declaration, throw away any variable type sizes of types
13542 defined inside that declaration. There is no use computing them in the
13543 following function definition. */
13544 if (current_binding_level
== global_binding_level
)
13545 get_pending_sizes ();
13548 /* Finish up a function declaration and compile that function
13549 all the way to assembler language output. The free the storage
13550 for the function definition.
13552 This is called after parsing the body of the function definition.
13554 NESTED is nonzero if the function being finished is nested in another. */
13557 finish_function (int nested
)
13559 register tree fndecl
= current_function_decl
;
13561 assert (fndecl
!= NULL_TREE
);
13562 if (TREE_CODE (fndecl
) != ERROR_MARK
)
13565 assert (DECL_CONTEXT (fndecl
) != NULL_TREE
);
13567 assert (DECL_CONTEXT (fndecl
) == NULL_TREE
);
13570 /* TREE_READONLY (fndecl) = 1;
13571 This caused &foo to be of type ptr-to-const-function
13572 which then got a warning when stored in a ptr-to-function variable. */
13574 poplevel (1, 0, 1);
13576 if (TREE_CODE (fndecl
) != ERROR_MARK
)
13578 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl
)) = fndecl
;
13580 /* Must mark the RESULT_DECL as being in this function. */
13582 DECL_CONTEXT (DECL_RESULT (fndecl
)) = fndecl
;
13584 /* Obey `register' declarations if `setjmp' is called in this fn. */
13585 /* Generate rtl for function exit. */
13586 expand_function_end ();
13588 /* If this is a nested function, protect the local variables in the stack
13589 above us from being collected while we're compiling this function. */
13591 ggc_push_context ();
13593 /* Run the optimizers and output the assembler code for this function. */
13594 rest_of_compilation (fndecl
);
13595 if (! DECL_DEFER_OUTPUT (fndecl
))
13597 free_after_compilation (cfun
);
13598 DECL_STRUCT_FUNCTION (fndecl
) = 0;
13602 /* Undo the GC context switch. */
13604 ggc_pop_context ();
13607 if (TREE_CODE (fndecl
) != ERROR_MARK
13609 && DECL_STRUCT_FUNCTION (fndecl
) == 0)
13611 /* Stop pointing to the local nodes about to be freed. */
13612 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13613 function definition. */
13614 /* For a nested function, this is done in pop_f_function_context. */
13615 /* If rest_of_compilation set this to 0, leave it 0. */
13616 if (DECL_INITIAL (fndecl
) != 0)
13617 DECL_INITIAL (fndecl
) = error_mark_node
;
13618 DECL_ARGUMENTS (fndecl
) = 0;
13623 /* Let the error reporting routines know that we're outside a function.
13624 For a nested function, this value is used in pop_c_function_context
13625 and then reset via pop_function_context. */
13626 ffecom_outer_function_decl_
= current_function_decl
= NULL
;
13630 /* Plug-in replacement for identifying the name of a decl and, for a
13631 function, what we call it in diagnostics. For now, "program unit"
13632 should suffice, since it's a bit of a hassle to figure out which
13633 of several kinds of things it is. Note that it could conceivably
13634 be a statement function, which probably isn't really a program unit
13635 per se, but if that comes up, it should be easy to check (being a
13636 nested function and all). */
13638 static const char *
13639 ffe_printable_name (tree decl
, int v
)
13641 /* Just to keep GCC quiet about the unused variable.
13642 In theory, differing values of V should produce different
13647 if (TREE_CODE (decl
) == ERROR_MARK
)
13648 return "erroneous code";
13649 return IDENTIFIER_POINTER (DECL_NAME (decl
));
13653 /* g77's function to print out name of current function that caused
13657 ffe_print_error_function (diagnostic_context
*context
__attribute__((unused
)),
13660 static ffeglobal last_g
= NULL
;
13661 static ffesymbol last_s
= NULL
;
13666 if ((ffecom_primary_entry_
== NULL
)
13667 || (ffesymbol_global (ffecom_primary_entry_
) == NULL
))
13675 g
= ffesymbol_global (ffecom_primary_entry_
);
13676 if (ffecom_nested_entry_
== NULL
)
13678 s
= ffecom_primary_entry_
;
13679 kind
= _(ffeinfo_kind_message (ffesymbol_kind (s
)));
13683 s
= ffecom_nested_entry_
;
13684 kind
= _("In statement function");
13688 if ((last_g
!= g
) || (last_s
!= s
))
13691 fprintf (stderr
, "%s: ", file
);
13694 fprintf (stderr
, _("Outside of any program unit:\n"));
13697 const char *name
= ffesymbol_text (s
);
13699 fprintf (stderr
, "%s `%s':\n", kind
, name
);
13707 /* Similar to `lookup_name' but look only at current binding level. */
13710 lookup_name_current_level (tree name
)
13714 if (current_binding_level
== global_binding_level
)
13715 return IDENTIFIER_GLOBAL_VALUE (name
);
13717 if (IDENTIFIER_LOCAL_VALUE (name
) == 0)
13720 for (t
= current_binding_level
->names
; t
; t
= TREE_CHAIN (t
))
13721 if (DECL_NAME (t
) == name
)
13727 /* Create a new `struct f_binding_level'. */
13729 static struct f_binding_level
*
13730 make_binding_level (void)
13733 return ggc_alloc (sizeof (struct f_binding_level
));
13736 /* Save and restore the variables in this file and elsewhere
13737 that keep track of the progress of compilation of the current function.
13738 Used for nested functions. */
13742 struct f_function
*next
;
13744 tree shadowed_labels
;
13745 struct f_binding_level
*binding_level
;
13748 struct f_function
*f_function_chain
;
13750 /* Restore the variables used during compilation of a C function. */
13753 pop_f_function_context (void)
13755 struct f_function
*p
= f_function_chain
;
13758 /* Bring back all the labels that were shadowed. */
13759 for (link
= shadowed_labels
; link
; link
= TREE_CHAIN (link
))
13760 if (DECL_NAME (TREE_VALUE (link
)) != 0)
13761 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link
)))
13762 = TREE_VALUE (link
);
13764 if (current_function_decl
!= error_mark_node
13765 && DECL_STRUCT_FUNCTION (current_function_decl
) == 0)
13767 /* Stop pointing to the local nodes about to be freed. */
13768 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13769 function definition. */
13770 DECL_INITIAL (current_function_decl
) = error_mark_node
;
13771 DECL_ARGUMENTS (current_function_decl
) = 0;
13774 pop_function_context ();
13776 f_function_chain
= p
->next
;
13778 named_labels
= p
->named_labels
;
13779 shadowed_labels
= p
->shadowed_labels
;
13780 current_binding_level
= p
->binding_level
;
13785 /* Save and reinitialize the variables
13786 used during compilation of a C function. */
13789 push_f_function_context (void)
13791 struct f_function
*p
= xmalloc (sizeof (struct f_function
));
13793 push_function_context ();
13795 p
->next
= f_function_chain
;
13796 f_function_chain
= p
;
13798 p
->named_labels
= named_labels
;
13799 p
->shadowed_labels
= shadowed_labels
;
13800 p
->binding_level
= current_binding_level
;
13804 push_parm_decl (tree parm
)
13806 int old_immediate_size_expand
= immediate_size_expand
;
13808 /* Don't try computing parm sizes now -- wait till fn is called. */
13810 immediate_size_expand
= 0;
13812 /* Fill in arg stuff. */
13814 DECL_ARG_TYPE (parm
) = TREE_TYPE (parm
);
13815 DECL_ARG_TYPE_AS_WRITTEN (parm
) = TREE_TYPE (parm
);
13816 TREE_READONLY (parm
) = 1; /* All implementation args are read-only. */
13818 parm
= pushdecl (parm
);
13820 immediate_size_expand
= old_immediate_size_expand
;
13822 finish_decl (parm
, NULL_TREE
, FALSE
);
13825 /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
13828 pushdecl_top_level (tree x
)
13831 register struct f_binding_level
*b
= current_binding_level
;
13832 register tree f
= current_function_decl
;
13834 current_binding_level
= global_binding_level
;
13835 current_function_decl
= NULL_TREE
;
13837 current_binding_level
= b
;
13838 current_function_decl
= f
;
13842 /* Store the list of declarations of the current level.
13843 This is done for the parameter declarations of a function being defined,
13844 after they are modified in the light of any missing parameters. */
13847 storedecls (tree decls
)
13849 return current_binding_level
->names
= decls
;
13852 /* Store the parameter declarations into the current function declaration.
13853 This is called after parsing the parameter declarations, before
13854 digesting the body of the function.
13856 For an old-style definition, modify the function's type
13857 to specify at least the number of arguments. */
13860 store_parm_decls (int is_main_program UNUSED
)
13862 register tree fndecl
= current_function_decl
;
13864 if (fndecl
== error_mark_node
)
13867 /* This is a chain of PARM_DECLs from old-style parm declarations. */
13868 DECL_ARGUMENTS (fndecl
) = storedecls (nreverse (getdecls ()));
13870 /* Initialize the RTL code for the function. */
13871 init_function_start (fndecl
);
13873 /* Set up parameters and prepare for return, for the function. */
13874 expand_function_start (fndecl
, 0);
13878 start_decl (tree decl
, bool is_top_level
)
13881 bool at_top_level
= (current_binding_level
== global_binding_level
);
13882 bool top_level
= is_top_level
|| at_top_level
;
13884 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13886 assert (!is_top_level
|| !at_top_level
);
13888 if (DECL_INITIAL (decl
) != NULL_TREE
)
13890 assert (DECL_INITIAL (decl
) == error_mark_node
);
13891 assert (!DECL_EXTERNAL (decl
));
13893 else if (top_level
)
13894 assert ((TREE_STATIC (decl
) == 1) || DECL_EXTERNAL (decl
) == 1);
13896 /* For Fortran, we by default put things in .common when possible. */
13897 DECL_COMMON (decl
) = 1;
13899 /* Add this decl to the current binding level. TEM may equal DECL or it may
13900 be a previous decl of the same name. */
13902 tem
= pushdecl_top_level (decl
);
13904 tem
= pushdecl (decl
);
13906 /* For a local variable, define the RTL now. */
13908 /* But not if this is a duplicate decl and we preserved the rtl from the
13909 previous one (which may or may not happen). */
13910 && !DECL_RTL_SET_P (tem
))
13912 if (TYPE_SIZE (TREE_TYPE (tem
)) != 0)
13914 else if (TREE_CODE (TREE_TYPE (tem
)) == ARRAY_TYPE
13915 && DECL_INITIAL (tem
) != 0)
13922 /* Create the FUNCTION_DECL for a function definition.
13923 DECLSPECS and DECLARATOR are the parts of the declaration;
13924 they describe the function's name and the type it returns,
13925 but twisted together in a fashion that parallels the syntax of C.
13927 This function creates a binding context for the function body
13928 as well as setting up the FUNCTION_DECL in current_function_decl.
13930 Returns 1 on success. If the DECLARATOR is not suitable for a function
13931 (it defines a datum instead), we return 0, which tells
13932 ffe_parse_file to report a parse error.
13934 NESTED is nonzero for a function nested within another function. */
13937 start_function (tree name
, tree type
, int nested
, int public)
13941 int old_immediate_size_expand
= immediate_size_expand
;
13944 shadowed_labels
= 0;
13946 /* Don't expand any sizes in the return type of the function. */
13947 immediate_size_expand
= 0;
13952 assert (current_function_decl
!= NULL_TREE
);
13953 assert (DECL_CONTEXT (current_function_decl
) == NULL_TREE
);
13957 assert (current_function_decl
== NULL_TREE
);
13960 if (TREE_CODE (type
) == ERROR_MARK
)
13961 decl1
= current_function_decl
= error_mark_node
;
13964 decl1
= build_decl (FUNCTION_DECL
,
13967 TREE_PUBLIC (decl1
) = public ? 1 : 0;
13969 DECL_INLINE (decl1
) = 1;
13970 TREE_STATIC (decl1
) = 1;
13971 DECL_EXTERNAL (decl1
) = 0;
13973 announce_function (decl1
);
13975 /* Make the init_value nonzero so pushdecl knows this is not tentative.
13976 error_mark_node is replaced below (in poplevel) with the BLOCK. */
13977 DECL_INITIAL (decl1
) = error_mark_node
;
13979 /* Record the decl so that the function name is defined. If we already have
13980 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
13982 current_function_decl
= pushdecl (decl1
);
13986 ffecom_outer_function_decl_
= current_function_decl
;
13989 current_binding_level
->prep_state
= 2;
13991 if (TREE_CODE (current_function_decl
) != ERROR_MARK
)
13993 make_decl_rtl (current_function_decl
, NULL
);
13995 restype
= TREE_TYPE (TREE_TYPE (current_function_decl
));
13996 DECL_RESULT (current_function_decl
)
13997 = build_decl (RESULT_DECL
, NULL_TREE
, restype
);
14000 if (!nested
&& (TREE_CODE (current_function_decl
) != ERROR_MARK
))
14001 TREE_ADDRESSABLE (current_function_decl
) = 1;
14003 immediate_size_expand
= old_immediate_size_expand
;
14006 /* Here are the public functions the GNU back end needs. */
14009 convert (tree type
, tree expr
)
14011 register tree e
= expr
;
14012 register enum tree_code code
= TREE_CODE (type
);
14014 if (type
== TREE_TYPE (e
)
14015 || TREE_CODE (e
) == ERROR_MARK
)
14017 if (TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (TREE_TYPE (e
)))
14018 return fold (build1 (NOP_EXPR
, type
, e
));
14019 if (TREE_CODE (TREE_TYPE (e
)) == ERROR_MARK
14020 || code
== ERROR_MARK
)
14021 return error_mark_node
;
14022 if (TREE_CODE (TREE_TYPE (e
)) == VOID_TYPE
)
14024 assert ("void value not ignored as it ought to be" == NULL
);
14025 return error_mark_node
;
14027 if (code
== VOID_TYPE
)
14028 return build1 (CONVERT_EXPR
, type
, e
);
14029 if ((code
!= RECORD_TYPE
)
14030 && (TREE_CODE (TREE_TYPE (e
)) == RECORD_TYPE
))
14031 e
= ffecom_1 (REALPART_EXPR
, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e
))),
14033 if (code
== INTEGER_TYPE
|| code
== ENUMERAL_TYPE
)
14034 return fold (convert_to_integer (type
, e
));
14035 if (code
== POINTER_TYPE
)
14036 return fold (convert_to_pointer (type
, e
));
14037 if (code
== REAL_TYPE
)
14038 return fold (convert_to_real (type
, e
));
14039 if (code
== COMPLEX_TYPE
)
14040 return fold (convert_to_complex (type
, e
));
14041 if (code
== RECORD_TYPE
)
14042 return fold (ffecom_convert_to_complex_ (type
, e
));
14044 assert ("conversion to non-scalar type requested" == NULL
);
14045 return error_mark_node
;
14048 /* Return the list of declarations of the current level.
14049 Note that this list is in reverse order unless/until
14050 you nreverse it; and when you do nreverse it, you must
14051 store the result back using `storedecls' or you will lose. */
14056 return current_binding_level
->names
;
14059 /* Nonzero if we are currently in the global binding level. */
14062 global_bindings_p (void)
14064 return current_binding_level
== global_binding_level
;
14068 ffecom_init_decl_processing (void)
14075 /* Delete the node BLOCK from the current binding level.
14076 This is used for the block inside a stmt expr ({...})
14077 so that the block can be reinserted where appropriate. */
14080 delete_block (tree block
)
14083 if (current_binding_level
->blocks
== block
)
14084 current_binding_level
->blocks
= TREE_CHAIN (block
);
14085 for (t
= current_binding_level
->blocks
; t
;)
14087 if (TREE_CHAIN (t
) == block
)
14088 TREE_CHAIN (t
) = TREE_CHAIN (block
);
14090 t
= TREE_CHAIN (t
);
14092 TREE_CHAIN (block
) = NULL
;
14093 /* Clear TREE_USED which is always set by poplevel.
14094 The flag is set again if insert_block is called. */
14095 TREE_USED (block
) = 0;
14099 insert_block (tree block
)
14101 TREE_USED (block
) = 1;
14102 current_binding_level
->blocks
14103 = chainon (current_binding_level
->blocks
, block
);
14106 /* Each front end provides its own. */
14107 static bool ffe_init (void);
14108 static void ffe_finish (void);
14109 static bool ffe_post_options (const char **);
14110 static void ffe_print_identifier (FILE *, tree
, int);
14112 struct language_function
GTY(())
14117 #undef LANG_HOOKS_NAME
14118 #define LANG_HOOKS_NAME "GNU F77"
14119 #undef LANG_HOOKS_INIT
14120 #define LANG_HOOKS_INIT ffe_init
14121 #undef LANG_HOOKS_FINISH
14122 #define LANG_HOOKS_FINISH ffe_finish
14123 #undef LANG_HOOKS_INIT_OPTIONS
14124 #define LANG_HOOKS_INIT_OPTIONS ffe_init_options
14125 #undef LANG_HOOKS_HANDLE_OPTION
14126 #define LANG_HOOKS_HANDLE_OPTION ffe_handle_option
14127 #undef LANG_HOOKS_POST_OPTIONS
14128 #define LANG_HOOKS_POST_OPTIONS ffe_post_options
14129 #undef LANG_HOOKS_PARSE_FILE
14130 #define LANG_HOOKS_PARSE_FILE ffe_parse_file
14131 #undef LANG_HOOKS_MARK_ADDRESSABLE
14132 #define LANG_HOOKS_MARK_ADDRESSABLE ffe_mark_addressable
14133 #undef LANG_HOOKS_PRINT_IDENTIFIER
14134 #define LANG_HOOKS_PRINT_IDENTIFIER ffe_print_identifier
14135 #undef LANG_HOOKS_DECL_PRINTABLE_NAME
14136 #define LANG_HOOKS_DECL_PRINTABLE_NAME ffe_printable_name
14137 #undef LANG_HOOKS_PRINT_ERROR_FUNCTION
14138 #define LANG_HOOKS_PRINT_ERROR_FUNCTION ffe_print_error_function
14139 #undef LANG_HOOKS_TRUTHVALUE_CONVERSION
14140 #define LANG_HOOKS_TRUTHVALUE_CONVERSION ffe_truthvalue_conversion
14142 #undef LANG_HOOKS_TYPE_FOR_MODE
14143 #define LANG_HOOKS_TYPE_FOR_MODE ffe_type_for_mode
14144 #undef LANG_HOOKS_TYPE_FOR_SIZE
14145 #define LANG_HOOKS_TYPE_FOR_SIZE ffe_type_for_size
14146 #undef LANG_HOOKS_SIGNED_TYPE
14147 #define LANG_HOOKS_SIGNED_TYPE ffe_signed_type
14148 #undef LANG_HOOKS_UNSIGNED_TYPE
14149 #define LANG_HOOKS_UNSIGNED_TYPE ffe_unsigned_type
14150 #undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
14151 #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE ffe_signed_or_unsigned_type
14153 /* We do not wish to use alias-set based aliasing at all. Used in the
14154 extreme (every object with its own set, with equivalences recorded) it
14155 might be helpful, but there are problems when it comes to inlining. We
14156 get on ok with flag_argument_noalias, and alias-set aliasing does
14157 currently limit how stack slots can be reused, which is a lose. */
14158 #undef LANG_HOOKS_GET_ALIAS_SET
14159 #define LANG_HOOKS_GET_ALIAS_SET hook_get_alias_set_0
14161 const struct lang_hooks lang_hooks
= LANG_HOOKS_INITIALIZER
;
14163 /* Table indexed by tree code giving a string containing a character
14164 classifying the tree code. Possibilities are
14165 t, d, s, c, r, <, 1, 2 and e. See tree.def for details. */
14167 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
14169 const char tree_code_type
[] = {
14170 #include "tree.def"
14174 /* Table indexed by tree code giving number of expression
14175 operands beyond the fixed part of the node structure.
14176 Not used for types or decls. */
14178 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
14180 const unsigned char tree_code_length
[] = {
14181 #include "tree.def"
14185 /* Names of tree components.
14186 Used for printing out the tree and error messages. */
14187 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
14189 const char *const tree_code_name
[] = {
14190 #include "tree.def"
14195 ffe_post_options (const char **pfilename
)
14197 const char *filename
= *pfilename
;
14199 /* Open input file. */
14200 if (filename
== 0 || !strcmp (filename
, "-"))
14203 filename
= "stdin";
14206 finput
= fopen (filename
, "r");
14209 fatal_error ("can't open %s: %m", filename
);
14218 #ifdef IO_BUFFER_SIZE
14219 setvbuf (finput
, xmalloc (IO_BUFFER_SIZE
), _IOFBF
, IO_BUFFER_SIZE
);
14222 ffecom_init_decl_processing ();
14224 /* If the file is output from cpp, it should contain a first line
14225 `# 1 "real-filename"', and the current design of gcc (toplev.c
14226 in particular and the way it sets up information relied on by
14227 INCLUDE) requires that we read this now, and store the
14228 "real-filename" info in master_input_filename. Ask the lexer
14229 to try doing this. */
14230 ffelex_hash_kludge (finput
);
14232 push_srcloc (input_filename
, 0);
14234 /* FIXME: The ffelex_hash_kludge code needs to be cleaned up to
14235 set the new file name. Maybe in ffe_post_options. */
14242 ffe_terminate_0 ();
14244 if (ffe_is_ffedebug ())
14245 malloc_pool_display (malloc_pool_image ());
14251 ffe_mark_addressable (tree exp
)
14253 register tree x
= exp
;
14255 switch (TREE_CODE (x
))
14258 case COMPONENT_REF
:
14260 x
= TREE_OPERAND (x
, 0);
14264 TREE_ADDRESSABLE (x
) = 1;
14271 if (DECL_REGISTER (x
) && !TREE_ADDRESSABLE (x
)
14272 && DECL_NONLOCAL (x
))
14274 if (TREE_PUBLIC (x
))
14276 assert ("address of global register var requested" == NULL
);
14279 assert ("address of register variable requested" == NULL
);
14281 else if (DECL_REGISTER (x
) && !TREE_ADDRESSABLE (x
))
14283 if (TREE_PUBLIC (x
))
14285 assert ("address of global register var requested" == NULL
);
14288 assert ("address of register var requested" == NULL
);
14290 put_var_into_stack (x
, /*rescan=*/true);
14293 case FUNCTION_DECL
:
14294 TREE_ADDRESSABLE (x
) = 1;
14295 #if 0 /* poplevel deals with this now. */
14296 if (DECL_CONTEXT (x
) == 0)
14297 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x
)) = 1;
14305 /* Exit a binding level.
14306 Pop the level off, and restore the state of the identifier-decl mappings
14307 that were in effect when this level was entered.
14309 If KEEP is nonzero, this level had explicit declarations, so
14310 and create a "block" (a BLOCK node) for the level
14311 to record its declarations and subblocks for symbol table output.
14313 If FUNCTIONBODY is nonzero, this level is the body of a function,
14314 so create a block as if KEEP were set and also clear out all
14317 If REVERSE is nonzero, reverse the order of decls before putting
14318 them into the BLOCK. */
14321 poplevel (int keep
, int reverse
, int functionbody
)
14323 register tree link
;
14324 /* The chain of decls was accumulated in reverse order.
14325 Put it into forward order, just for cleanliness. */
14327 tree subblocks
= current_binding_level
->blocks
;
14330 int block_previously_created
;
14332 /* Get the decls in the order they were written.
14333 Usually current_binding_level->names is in reverse order.
14334 But parameter decls were previously put in forward order. */
14337 current_binding_level
->names
14338 = decls
= nreverse (current_binding_level
->names
);
14340 decls
= current_binding_level
->names
;
14342 /* Output any nested inline functions within this block
14343 if they weren't already output. */
14345 for (decl
= decls
; decl
; decl
= TREE_CHAIN (decl
))
14346 if (TREE_CODE (decl
) == FUNCTION_DECL
14347 && ! TREE_ASM_WRITTEN (decl
)
14348 && DECL_INITIAL (decl
) != 0
14349 && TREE_ADDRESSABLE (decl
))
14351 /* If this decl was copied from a file-scope decl
14352 on account of a block-scope extern decl,
14353 propagate TREE_ADDRESSABLE to the file-scope decl.
14355 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
14356 true, since then the decl goes through save_for_inline_copying. */
14357 if (DECL_ABSTRACT_ORIGIN (decl
) != 0
14358 && DECL_ABSTRACT_ORIGIN (decl
) != decl
)
14359 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl
)) = 1;
14360 else if (DECL_STRUCT_FUNCTION (decl
) != 0)
14362 push_function_context ();
14363 output_inline_function (decl
);
14364 pop_function_context ();
14368 /* If there were any declarations or structure tags in that level,
14369 or if this level is a function body,
14370 create a BLOCK to record them for the life of this function. */
14373 block_previously_created
= (current_binding_level
->this_block
!= 0);
14374 if (block_previously_created
)
14375 block
= current_binding_level
->this_block
;
14376 else if (keep
|| functionbody
)
14377 block
= make_node (BLOCK
);
14380 BLOCK_VARS (block
) = decls
;
14381 BLOCK_SUBBLOCKS (block
) = subblocks
;
14384 /* In each subblock, record that this is its superior. */
14386 for (link
= subblocks
; link
; link
= TREE_CHAIN (link
))
14387 BLOCK_SUPERCONTEXT (link
) = block
;
14389 /* Clear out the meanings of the local variables of this level. */
14391 for (link
= decls
; link
; link
= TREE_CHAIN (link
))
14393 if (DECL_NAME (link
) != 0)
14395 /* If the ident. was used or addressed via a local extern decl,
14396 don't forget that fact. */
14397 if (DECL_EXTERNAL (link
))
14399 if (TREE_USED (link
))
14400 TREE_USED (DECL_NAME (link
)) = 1;
14401 if (TREE_ADDRESSABLE (link
))
14402 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link
)) = 1;
14404 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link
)) = 0;
14408 /* If the level being exited is the top level of a function,
14409 check over all the labels, and clear out the current
14410 (function local) meanings of their names. */
14414 /* If this is the top level block of a function,
14415 the vars are the function's parameters.
14416 Don't leave them in the BLOCK because they are
14417 found in the FUNCTION_DECL instead. */
14419 BLOCK_VARS (block
) = 0;
14422 /* Pop the current level, and free the structure for reuse. */
14425 register struct f_binding_level
*level
= current_binding_level
;
14426 current_binding_level
= current_binding_level
->level_chain
;
14428 level
->level_chain
= free_binding_level
;
14429 free_binding_level
= level
;
14432 /* Dispose of the block that we just made inside some higher level. */
14434 && current_function_decl
!= error_mark_node
)
14435 DECL_INITIAL (current_function_decl
) = block
;
14438 if (!block_previously_created
)
14439 current_binding_level
->blocks
14440 = chainon (current_binding_level
->blocks
, block
);
14442 /* If we did not make a block for the level just exited,
14443 any blocks made for inner levels
14444 (since they cannot be recorded as subblocks in that level)
14445 must be carried forward so they will later become subblocks
14446 of something else. */
14447 else if (subblocks
)
14448 current_binding_level
->blocks
14449 = chainon (current_binding_level
->blocks
, subblocks
);
14452 TREE_USED (block
) = 1;
14457 ffe_print_identifier (FILE *file
, tree node
, int indent
)
14459 print_node (file
, "global", IDENTIFIER_GLOBAL_VALUE (node
), indent
+ 4);
14460 print_node (file
, "local", IDENTIFIER_LOCAL_VALUE (node
), indent
+ 4);
14463 /* Record a decl-node X as belonging to the current lexical scope.
14464 Check for errors (such as an incompatible declaration for the same
14465 name already seen in the same scope).
14467 Returns either X or an old decl for the same name.
14468 If an old decl is returned, it may have been smashed
14469 to agree with what X says. */
14475 register tree name
= DECL_NAME (x
);
14476 register struct f_binding_level
*b
= current_binding_level
;
14478 if ((TREE_CODE (x
) == FUNCTION_DECL
)
14479 && (DECL_INITIAL (x
) == 0)
14480 && DECL_EXTERNAL (x
))
14481 DECL_CONTEXT (x
) = NULL_TREE
;
14483 DECL_CONTEXT (x
) = current_function_decl
;
14487 if (IDENTIFIER_INVENTED (name
))
14489 DECL_ARTIFICIAL (x
) = 1;
14490 DECL_IN_SYSTEM_HEADER (x
) = 1;
14493 t
= lookup_name_current_level (name
);
14495 assert ((t
== NULL_TREE
) || (DECL_CONTEXT (x
) == NULL_TREE
));
14497 /* Don't push non-parms onto list for parms until we understand
14498 why we're doing this and whether it works. */
14500 assert ((b
== global_binding_level
)
14501 || !ffecom_transform_only_dummies_
14502 || TREE_CODE (x
) == PARM_DECL
);
14504 if ((t
!= NULL_TREE
) && duplicate_decls (x
, t
))
14507 /* If we are processing a typedef statement, generate a whole new
14508 ..._TYPE node (which will be just an variant of the existing
14509 ..._TYPE node with identical properties) and then install the
14510 TYPE_DECL node generated to represent the typedef name as the
14511 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
14513 The whole point here is to end up with a situation where each and every
14514 ..._TYPE node the compiler creates will be uniquely associated with
14515 AT MOST one node representing a typedef name. This way, even though
14516 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
14517 (i.e. "typedef name") nodes very early on, later parts of the
14518 compiler can always do the reverse translation and get back the
14519 corresponding typedef name. For example, given:
14521 typedef struct S MY_TYPE; MY_TYPE object;
14523 Later parts of the compiler might only know that `object' was of type
14524 `struct S' if it were not for code just below. With this code
14525 however, later parts of the compiler see something like:
14527 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
14529 And they can then deduce (from the node for type struct S') that the
14530 original object declaration was:
14534 Being able to do this is important for proper support of protoize, and
14535 also for generating precise symbolic debugging information which
14536 takes full account of the programmer's (typedef) vocabulary.
14538 Obviously, we don't want to generate a duplicate ..._TYPE node if the
14539 TYPE_DECL node that we are now processing really represents a
14540 standard built-in type.
14542 Since all standard types are effectively declared at line zero in the
14543 source file, we can easily check to see if we are working on a
14544 standard type by checking the current value of lineno. */
14546 if (TREE_CODE (x
) == TYPE_DECL
)
14548 if (DECL_SOURCE_LINE (x
) == 0)
14550 if (TYPE_NAME (TREE_TYPE (x
)) == 0)
14551 TYPE_NAME (TREE_TYPE (x
)) = x
;
14553 else if (TREE_TYPE (x
) != error_mark_node
)
14555 tree tt
= TREE_TYPE (x
);
14557 tt
= build_type_copy (tt
);
14558 TYPE_NAME (tt
) = x
;
14559 TREE_TYPE (x
) = tt
;
14563 /* This name is new in its binding level. Install the new declaration
14565 if (b
== global_binding_level
)
14566 IDENTIFIER_GLOBAL_VALUE (name
) = x
;
14568 IDENTIFIER_LOCAL_VALUE (name
) = x
;
14571 /* Put decls on list in reverse order. We will reverse them later if
14573 TREE_CHAIN (x
) = b
->names
;
14579 /* Nonzero if the current level needs to have a BLOCK made. */
14582 kept_level_p (void)
14586 for (decl
= current_binding_level
->names
;
14588 decl
= TREE_CHAIN (decl
))
14590 if (TREE_USED (decl
) || TREE_CODE (decl
) != VAR_DECL
14591 || (DECL_NAME (decl
) && ! DECL_ARTIFICIAL (decl
)))
14592 /* Currently, there aren't supposed to be non-artificial names
14593 at other than the top block for a function -- they're
14594 believed to always be temps. But it's wise to check anyway. */
14600 /* Enter a new binding level.
14601 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
14602 not for that of tags. */
14605 pushlevel (int tag_transparent
)
14607 register struct f_binding_level
*newlevel
= NULL_BINDING_LEVEL
;
14609 assert (! tag_transparent
);
14611 if (current_binding_level
== global_binding_level
)
14616 /* Reuse or create a struct for this binding level. */
14618 if (free_binding_level
)
14620 newlevel
= free_binding_level
;
14621 free_binding_level
= free_binding_level
->level_chain
;
14625 newlevel
= make_binding_level ();
14628 /* Add this level to the front of the chain (stack) of levels that
14631 *newlevel
= clear_binding_level
;
14632 newlevel
->level_chain
= current_binding_level
;
14633 current_binding_level
= newlevel
;
14636 /* Set the BLOCK node for the innermost scope
14637 (the one we are currently in). */
14640 set_block (tree block
)
14642 current_binding_level
->this_block
= block
;
14643 current_binding_level
->names
= chainon (current_binding_level
->names
,
14644 BLOCK_VARS (block
));
14645 current_binding_level
->blocks
= chainon (current_binding_level
->blocks
,
14646 BLOCK_SUBBLOCKS (block
));
14650 ffe_signed_or_unsigned_type (int unsignedp
, tree type
)
14654 if (! INTEGRAL_TYPE_P (type
))
14656 if (TYPE_PRECISION (type
) == TYPE_PRECISION (signed_char_type_node
))
14657 return unsignedp
? unsigned_char_type_node
: signed_char_type_node
;
14658 if (TYPE_PRECISION (type
) == TYPE_PRECISION (integer_type_node
))
14659 return unsignedp
? unsigned_type_node
: integer_type_node
;
14660 if (TYPE_PRECISION (type
) == TYPE_PRECISION (short_integer_type_node
))
14661 return unsignedp
? short_unsigned_type_node
: short_integer_type_node
;
14662 if (TYPE_PRECISION (type
) == TYPE_PRECISION (long_integer_type_node
))
14663 return unsignedp
? long_unsigned_type_node
: long_integer_type_node
;
14664 if (TYPE_PRECISION (type
) == TYPE_PRECISION (long_long_integer_type_node
))
14665 return (unsignedp
? long_long_unsigned_type_node
14666 : long_long_integer_type_node
);
14668 type2
= ffe_type_for_size (TYPE_PRECISION (type
), unsignedp
);
14669 if (type2
== NULL_TREE
)
14676 ffe_signed_type (tree type
)
14678 tree type1
= TYPE_MAIN_VARIANT (type
);
14679 ffeinfoKindtype kt
;
14682 if (type1
== unsigned_char_type_node
|| type1
== char_type_node
)
14683 return signed_char_type_node
;
14684 if (type1
== unsigned_type_node
)
14685 return integer_type_node
;
14686 if (type1
== short_unsigned_type_node
)
14687 return short_integer_type_node
;
14688 if (type1
== long_unsigned_type_node
)
14689 return long_integer_type_node
;
14690 if (type1
== long_long_unsigned_type_node
)
14691 return long_long_integer_type_node
;
14692 #if 0 /* gcc/c-* files only */
14693 if (type1
== unsigned_intDI_type_node
)
14694 return intDI_type_node
;
14695 if (type1
== unsigned_intSI_type_node
)
14696 return intSI_type_node
;
14697 if (type1
== unsigned_intHI_type_node
)
14698 return intHI_type_node
;
14699 if (type1
== unsigned_intQI_type_node
)
14700 return intQI_type_node
;
14703 type2
= ffe_type_for_size (TYPE_PRECISION (type1
), 0);
14704 if (type2
!= NULL_TREE
)
14707 for (kt
= 0; kt
< ARRAY_SIZE (ffecom_tree_type
[0]); ++kt
)
14709 type2
= ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][kt
];
14711 if (type1
== type2
)
14712 return ffecom_tree_type
[FFEINFO_basictypeINTEGER
][kt
];
14718 /* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
14719 or validate its data type for an `if' or `while' statement or ?..: exp.
14721 This preparation consists of taking the ordinary
14722 representation of an expression expr and producing a valid tree
14723 boolean expression describing whether expr is nonzero. We could
14724 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
14725 but we optimize comparisons, &&, ||, and !.
14727 The resulting type should always be `integer_type_node'. */
14730 ffe_truthvalue_conversion (tree expr
)
14732 if (TREE_CODE (expr
) == ERROR_MARK
)
14735 #if 0 /* This appears to be wrong for C++. */
14736 /* These really should return error_mark_node after 2.4 is stable.
14737 But not all callers handle ERROR_MARK properly. */
14738 switch (TREE_CODE (TREE_TYPE (expr
)))
14741 error ("struct type value used where scalar is required");
14742 return integer_zero_node
;
14745 error ("union type value used where scalar is required");
14746 return integer_zero_node
;
14749 error ("array type value used where scalar is required");
14750 return integer_zero_node
;
14757 switch (TREE_CODE (expr
))
14759 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14760 or comparison expressions as truth values at this level. */
14762 case COMPONENT_REF
:
14763 /* A one-bit unsigned bit-field is already acceptable. */
14764 if (integer_onep (DECL_SIZE (TREE_OPERAND (expr
, 1)))
14765 && DECL_UNSIGNED (TREE_OPERAND (expr
, 1)))
14771 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14772 or comparison expressions as truth values at this level. */
14774 if (integer_zerop (TREE_OPERAND (expr
, 1)))
14775 return build_unary_op (TRUTH_NOT_EXPR
, TREE_OPERAND (expr
, 0), 0);
14777 case NE_EXPR
: case LE_EXPR
: case GE_EXPR
: case LT_EXPR
: case GT_EXPR
:
14778 case TRUTH_ANDIF_EXPR
:
14779 case TRUTH_ORIF_EXPR
:
14780 case TRUTH_AND_EXPR
:
14781 case TRUTH_OR_EXPR
:
14782 case TRUTH_XOR_EXPR
:
14783 TREE_TYPE (expr
) = integer_type_node
;
14790 return integer_zerop (expr
) ? integer_zero_node
: integer_one_node
;
14793 return real_zerop (expr
) ? integer_zero_node
: integer_one_node
;
14796 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr
, 0)))
14797 return build (COMPOUND_EXPR
, integer_type_node
,
14798 TREE_OPERAND (expr
, 0), integer_one_node
);
14800 return integer_one_node
;
14803 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr
, 1))
14804 ? TRUTH_OR_EXPR
: TRUTH_ORIF_EXPR
),
14806 ffe_truthvalue_conversion (TREE_OPERAND (expr
, 0)),
14807 ffe_truthvalue_conversion (TREE_OPERAND (expr
, 1)));
14812 /* These don't change whether an object is nonzero or zero. */
14813 return ffe_truthvalue_conversion (TREE_OPERAND (expr
, 0));
14817 /* These don't change whether an object is zero or nonzero, but
14818 we can't ignore them if their second arg has side-effects. */
14819 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr
, 1)))
14820 return build (COMPOUND_EXPR
, integer_type_node
, TREE_OPERAND (expr
, 1),
14821 ffe_truthvalue_conversion (TREE_OPERAND (expr
, 0)));
14823 return ffe_truthvalue_conversion (TREE_OPERAND (expr
, 0));
14827 /* Distribute the conversion into the arms of a COND_EXPR. */
14828 tree arg1
= TREE_OPERAND (expr
, 1);
14829 tree arg2
= TREE_OPERAND (expr
, 2);
14830 if (! VOID_TYPE_P (TREE_TYPE (arg1
)))
14831 arg1
= ffe_truthvalue_conversion (arg1
);
14832 if (! VOID_TYPE_P (TREE_TYPE (arg2
)))
14833 arg2
= ffe_truthvalue_conversion (arg2
);
14834 return fold (build (COND_EXPR
, integer_type_node
,
14835 TREE_OPERAND (expr
, 0), arg1
, arg2
));
14839 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
14840 since that affects how `default_conversion' will behave. */
14841 if (TREE_CODE (TREE_TYPE (expr
)) == REFERENCE_TYPE
14842 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr
, 0))) == REFERENCE_TYPE
)
14844 /* fall through... */
14846 /* If this is widening the argument, we can ignore it. */
14847 if (TYPE_PRECISION (TREE_TYPE (expr
))
14848 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr
, 0))))
14849 return ffe_truthvalue_conversion (TREE_OPERAND (expr
, 0));
14853 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
14855 if (TARGET_FLOAT_FORMAT
== IEEE_FLOAT_FORMAT
14856 && TREE_CODE (TREE_TYPE (expr
)) == REAL_TYPE
)
14858 /* fall through... */
14860 /* This and MINUS_EXPR can be changed into a comparison of the
14862 if (TREE_TYPE (TREE_OPERAND (expr
, 0))
14863 == TREE_TYPE (TREE_OPERAND (expr
, 1)))
14864 return ffecom_2 (NE_EXPR
, integer_type_node
,
14865 TREE_OPERAND (expr
, 0),
14866 TREE_OPERAND (expr
, 1));
14867 return ffecom_2 (NE_EXPR
, integer_type_node
,
14868 TREE_OPERAND (expr
, 0),
14869 fold (build1 (NOP_EXPR
,
14870 TREE_TYPE (TREE_OPERAND (expr
, 0)),
14871 TREE_OPERAND (expr
, 1))));
14874 if (integer_onep (TREE_OPERAND (expr
, 1)))
14879 #if 0 /* No such thing in Fortran. */
14880 if (warn_parentheses
&& C_EXP_ORIGINAL_CODE (expr
) == MODIFY_EXPR
)
14881 warning ("suggest parentheses around assignment used as truth value");
14889 if (TREE_CODE (TREE_TYPE (expr
)) == COMPLEX_TYPE
)
14891 ((TREE_SIDE_EFFECTS (expr
)
14892 ? TRUTH_OR_EXPR
: TRUTH_ORIF_EXPR
),
14894 ffe_truthvalue_conversion (ffecom_1 (REALPART_EXPR
,
14895 TREE_TYPE (TREE_TYPE (expr
)),
14897 ffe_truthvalue_conversion (ffecom_1 (IMAGPART_EXPR
,
14898 TREE_TYPE (TREE_TYPE (expr
)),
14901 return ffecom_2 (NE_EXPR
, integer_type_node
,
14903 convert (TREE_TYPE (expr
), integer_zero_node
));
14907 ffe_type_for_mode (enum machine_mode mode
, int unsignedp
)
14913 if (mode
== TYPE_MODE (integer_type_node
))
14914 return unsignedp
? unsigned_type_node
: integer_type_node
;
14916 if (mode
== TYPE_MODE (signed_char_type_node
))
14917 return unsignedp
? unsigned_char_type_node
: signed_char_type_node
;
14919 if (mode
== TYPE_MODE (short_integer_type_node
))
14920 return unsignedp
? short_unsigned_type_node
: short_integer_type_node
;
14922 if (mode
== TYPE_MODE (long_integer_type_node
))
14923 return unsignedp
? long_unsigned_type_node
: long_integer_type_node
;
14925 if (mode
== TYPE_MODE (long_long_integer_type_node
))
14926 return unsignedp
? long_long_unsigned_type_node
: long_long_integer_type_node
;
14928 #if HOST_BITS_PER_WIDE_INT >= 64
14929 if (mode
== TYPE_MODE (intTI_type_node
))
14930 return unsignedp
? unsigned_intTI_type_node
: intTI_type_node
;
14933 if (mode
== TYPE_MODE (float_type_node
))
14934 return float_type_node
;
14936 if (mode
== TYPE_MODE (double_type_node
))
14937 return double_type_node
;
14939 if (mode
== TYPE_MODE (long_double_type_node
))
14940 return long_double_type_node
;
14942 if (mode
== TYPE_MODE (build_pointer_type (char_type_node
)))
14943 return build_pointer_type (char_type_node
);
14945 if (mode
== TYPE_MODE (build_pointer_type (integer_type_node
)))
14946 return build_pointer_type (integer_type_node
);
14948 for (i
= 0; ((size_t) i
) < ARRAY_SIZE (ffecom_tree_type
); ++i
)
14949 for (j
= 0; ((size_t) j
) < ARRAY_SIZE (ffecom_tree_type
[0]); ++j
)
14951 if (((t
= ffecom_tree_type
[i
][j
]) != NULL_TREE
)
14952 && (mode
== TYPE_MODE (t
)))
14954 if ((i
== FFEINFO_basictypeINTEGER
) && unsignedp
)
14955 return ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][j
];
14965 ffe_type_for_size (unsigned bits
, int unsignedp
)
14967 ffeinfoKindtype kt
;
14970 if (bits
== TYPE_PRECISION (integer_type_node
))
14971 return unsignedp
? unsigned_type_node
: integer_type_node
;
14973 if (bits
== TYPE_PRECISION (signed_char_type_node
))
14974 return unsignedp
? unsigned_char_type_node
: signed_char_type_node
;
14976 if (bits
== TYPE_PRECISION (short_integer_type_node
))
14977 return unsignedp
? short_unsigned_type_node
: short_integer_type_node
;
14979 if (bits
== TYPE_PRECISION (long_integer_type_node
))
14980 return unsignedp
? long_unsigned_type_node
: long_integer_type_node
;
14982 if (bits
== TYPE_PRECISION (long_long_integer_type_node
))
14983 return (unsignedp
? long_long_unsigned_type_node
14984 : long_long_integer_type_node
);
14986 for (kt
= 0; kt
< ARRAY_SIZE (ffecom_tree_type
[0]); ++kt
)
14988 type_node
= ffecom_tree_type
[FFEINFO_basictypeINTEGER
][kt
];
14990 if ((type_node
!= NULL_TREE
) && (bits
== TYPE_PRECISION (type_node
)))
14991 return unsignedp
? ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][kt
]
14999 ffe_unsigned_type (tree type
)
15001 tree type1
= TYPE_MAIN_VARIANT (type
);
15002 ffeinfoKindtype kt
;
15005 if (type1
== signed_char_type_node
|| type1
== char_type_node
)
15006 return unsigned_char_type_node
;
15007 if (type1
== integer_type_node
)
15008 return unsigned_type_node
;
15009 if (type1
== short_integer_type_node
)
15010 return short_unsigned_type_node
;
15011 if (type1
== long_integer_type_node
)
15012 return long_unsigned_type_node
;
15013 if (type1
== long_long_integer_type_node
)
15014 return long_long_unsigned_type_node
;
15015 #if 0 /* gcc/c-* files only */
15016 if (type1
== intDI_type_node
)
15017 return unsigned_intDI_type_node
;
15018 if (type1
== intSI_type_node
)
15019 return unsigned_intSI_type_node
;
15020 if (type1
== intHI_type_node
)
15021 return unsigned_intHI_type_node
;
15022 if (type1
== intQI_type_node
)
15023 return unsigned_intQI_type_node
;
15026 type2
= ffe_type_for_size (TYPE_PRECISION (type1
), 1);
15027 if (type2
!= NULL_TREE
)
15030 for (kt
= 0; kt
< ARRAY_SIZE (ffecom_tree_type
[0]); ++kt
)
15032 type2
= ffecom_tree_type
[FFEINFO_basictypeINTEGER
][kt
];
15034 if (type1
== type2
)
15035 return ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][kt
];
15041 /* From gcc/cccp.c, the code to handle -I. */
15043 /* Skip leading "./" from a directory name.
15044 This may yield the empty string, which represents the current directory. */
15046 static const char *
15047 skip_redundant_dir_prefix (const char *dir
)
15049 while (dir
[0] == '.' && dir
[1] == '/')
15050 for (dir
+= 2; *dir
== '/'; dir
++)
15052 if (dir
[0] == '.' && !dir
[1])
15057 /* The file_name_map structure holds a mapping of file names for a
15058 particular directory. This mapping is read from the file named
15059 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15060 map filenames on a file system with severe filename restrictions,
15061 such as DOS. The format of the file name map file is just a series
15062 of lines with two tokens on each line. The first token is the name
15063 to map, and the second token is the actual name to use. */
15065 struct file_name_map
15067 struct file_name_map
*map_next
;
15072 #define FILE_NAME_MAP_FILE "header.gcc"
15074 /* Current maximum length of directory names in the search path
15075 for include files. (Altered as we get more of them.) */
15077 static int max_include_len
= 0;
15079 struct file_name_list
15081 struct file_name_list
*next
;
15083 /* Mapping of file names for this directory. */
15084 struct file_name_map
*name_map
;
15085 /* Nonzero if name_map is valid. */
15089 static struct file_name_list
*include
= NULL
; /* First dir to search */
15090 static struct file_name_list
*last_include
= NULL
; /* Last in chain */
15092 /* I/O buffer structure.
15093 The `fname' field is nonzero for source files and #include files
15094 and for the dummy text used for -D and -U.
15095 It is zero for rescanning results of macro expansion
15096 and for expanding macro arguments. */
15097 #define INPUT_STACK_MAX 400
15098 static struct file_buf
{
15100 /* Filename specified with #line command. */
15101 const char *nominal_fname
;
15102 /* Record where in the search path this file was found.
15103 For #include_next. */
15104 struct file_name_list
*dir
;
15106 ffewhereColumn column
;
15107 } instack
[INPUT_STACK_MAX
];
15109 static int last_error_tick
= 0; /* Incremented each time we print it. */
15111 /* Current nesting level of input sources.
15112 `instack[indepth]' is the level currently being read. */
15113 static int indepth
= -1;
15115 typedef struct file_buf FILE_BUF
;
15117 /* Nonzero means -I- has been seen,
15118 so don't look for #include "foo" the source-file directory. */
15119 static int ignore_srcdir
;
15121 #ifndef INCLUDE_LEN_FUDGE
15122 #define INCLUDE_LEN_FUDGE 0
15125 static void append_include_chain (struct file_name_list
*first
,
15126 struct file_name_list
*last
);
15127 static FILE *open_include_file (char *filename
,
15128 struct file_name_list
*searchptr
);
15129 static void print_containing_files (ffebadSeverity sev
);
15130 static char *read_filename_string (int ch
, FILE *f
);
15131 static struct file_name_map
*read_name_map (const char *dirname
);
15133 /* Append a chain of `struct file_name_list's
15134 to the end of the main include chain.
15135 FIRST is the beginning of the chain to append, and LAST is the end. */
15138 append_include_chain (struct file_name_list
*first
,
15139 struct file_name_list
*last
)
15141 struct file_name_list
*dir
;
15143 if (!first
|| !last
)
15149 last_include
->next
= first
;
15151 for (dir
= first
; ; dir
= dir
->next
) {
15152 int len
= strlen (dir
->fname
) + INCLUDE_LEN_FUDGE
;
15153 if (len
> max_include_len
)
15154 max_include_len
= len
;
15160 last_include
= last
;
15163 /* Try to open include file FILENAME. SEARCHPTR is the directory
15164 being tried from the include file search path. This function maps
15165 filenames on file systems based on information read by
15169 open_include_file (char *filename
, struct file_name_list
*searchptr
)
15171 register struct file_name_map
*map
;
15172 register char *from
;
15175 if (searchptr
&& ! searchptr
->got_name_map
)
15177 searchptr
->name_map
= read_name_map (searchptr
->fname
15178 ? searchptr
->fname
: ".");
15179 searchptr
->got_name_map
= 1;
15182 /* First check the mapping for the directory we are using. */
15183 if (searchptr
&& searchptr
->name_map
)
15186 if (searchptr
->fname
)
15187 from
+= strlen (searchptr
->fname
) + 1;
15188 for (map
= searchptr
->name_map
; map
; map
= map
->map_next
)
15190 if (! strcmp (map
->map_from
, from
))
15192 /* Found a match. */
15193 return fopen (map
->map_to
, "r");
15198 /* Try to find a mapping file for the particular directory we are
15199 looking in. Thus #include <sys/types.h> will look up sys/types.h
15200 in /usr/include/header.gcc and look up types.h in
15201 /usr/include/sys/header.gcc. */
15202 p
= strrchr (filename
, '/');
15203 #ifdef DIR_SEPARATOR
15204 if (! p
) p
= strrchr (filename
, DIR_SEPARATOR
);
15206 char *tmp
= strrchr (filename
, DIR_SEPARATOR
);
15207 if (tmp
!= NULL
&& tmp
> p
) p
= tmp
;
15213 && searchptr
->fname
15214 && strlen (searchptr
->fname
) == (size_t) (p
- filename
)
15215 && ! strncmp (searchptr
->fname
, filename
, (int) (p
- filename
)))
15217 /* FILENAME is in SEARCHPTR, which we've already checked. */
15218 return fopen (filename
, "r");
15224 map
= read_name_map (".");
15228 dir
= xmalloc (p
- filename
+ 1);
15229 memcpy (dir
, filename
, p
- filename
);
15230 dir
[p
- filename
] = '\0';
15232 map
= read_name_map (dir
);
15235 for (; map
; map
= map
->map_next
)
15236 if (! strcmp (map
->map_from
, from
))
15237 return fopen (map
->map_to
, "r");
15239 return fopen (filename
, "r");
15242 /* Print the file names and line numbers of the #include
15243 commands which led to the current file. */
15246 print_containing_files (ffebadSeverity sev
)
15248 FILE_BUF
*ip
= NULL
;
15254 /* If stack of files hasn't changed since we last printed
15255 this info, don't repeat it. */
15256 if (last_error_tick
== input_file_stack_tick
)
15259 for (i
= indepth
; i
>= 0; i
--)
15260 if (instack
[i
].fname
!= NULL
) {
15265 /* Give up if we don't find a source file. */
15269 /* Find the other, outer source files. */
15270 for (i
--; i
>= 0; i
--)
15271 if (instack
[i
].fname
!= NULL
)
15277 str1
= "In file included";
15289 /* xgettext:no-c-format */
15290 ffebad_start_msg ("%A from %B at %0%C", sev
);
15291 ffebad_here (0, ip
->line
, ip
->column
);
15292 ffebad_string (str1
);
15293 ffebad_string (ip
->nominal_fname
);
15294 ffebad_string (str2
);
15298 /* Record we have printed the status as of this time. */
15299 last_error_tick
= input_file_stack_tick
;
15302 /* Read a space delimited string of unlimited length from a stdio
15306 read_filename_string (int ch
, FILE *f
)
15312 set
= alloc
= xmalloc (len
+ 1);
15313 if (! ISSPACE (ch
))
15316 while ((ch
= getc (f
)) != EOF
&& ! ISSPACE (ch
))
15318 if (set
- alloc
== len
)
15321 alloc
= xrealloc (alloc
, len
+ 1);
15322 set
= alloc
+ len
/ 2;
15332 /* Read the file name map file for DIRNAME. */
15334 static struct file_name_map
*
15335 read_name_map (const char *dirname
)
15337 /* This structure holds a linked list of file name maps, one per
15339 struct file_name_map_list
15341 struct file_name_map_list
*map_list_next
;
15342 char *map_list_name
;
15343 struct file_name_map
*map_list_map
;
15345 static struct file_name_map_list
*map_list
;
15346 register struct file_name_map_list
*map_list_ptr
;
15350 int separator_needed
;
15352 dirname
= skip_redundant_dir_prefix (dirname
);
15354 for (map_list_ptr
= map_list
; map_list_ptr
;
15355 map_list_ptr
= map_list_ptr
->map_list_next
)
15356 if (! strcmp (map_list_ptr
->map_list_name
, dirname
))
15357 return map_list_ptr
->map_list_map
;
15359 map_list_ptr
= xmalloc (sizeof (struct file_name_map_list
));
15360 map_list_ptr
->map_list_name
= xstrdup (dirname
);
15361 map_list_ptr
->map_list_map
= NULL
;
15363 dirlen
= strlen (dirname
);
15364 separator_needed
= dirlen
!= 0 && dirname
[dirlen
- 1] != '/';
15365 if (separator_needed
)
15366 name
= concat (dirname
, "/", FILE_NAME_MAP_FILE
, NULL
);
15368 name
= concat (dirname
, FILE_NAME_MAP_FILE
, NULL
);
15369 f
= fopen (name
, "r");
15372 map_list_ptr
->map_list_map
= NULL
;
15377 while ((ch
= getc (f
)) != EOF
)
15380 struct file_name_map
*ptr
;
15384 from
= read_filename_string (ch
, f
);
15385 while ((ch
= getc (f
)) != EOF
&& ISSPACE (ch
) && ch
!= '\n')
15387 to
= read_filename_string (ch
, f
);
15389 ptr
= xmalloc (sizeof (struct file_name_map
));
15390 ptr
->map_from
= from
;
15392 /* Make the real filename absolute. */
15397 if (separator_needed
)
15398 ptr
->map_to
= concat (dirname
, "/", to
, NULL
);
15400 ptr
->map_to
= concat (dirname
, to
, NULL
);
15404 ptr
->map_next
= map_list_ptr
->map_list_map
;
15405 map_list_ptr
->map_list_map
= ptr
;
15407 while ((ch
= getc (f
)) != '\n')
15414 map_list_ptr
->map_list_next
= map_list
;
15415 map_list
= map_list_ptr
;
15417 return map_list_ptr
->map_list_map
;
15421 ffecom_file_ (const char *name
)
15425 /* Do partial setup of input buffer for the sake of generating
15426 early #line directives (when -g is in effect). */
15428 fp
= &instack
[++indepth
];
15429 memset (fp
, 0, sizeof (FILE_BUF
));
15432 fp
->nominal_fname
= fp
->fname
= name
;
15436 ffecom_close_include_ (FILE *f
)
15441 input_file_stack_tick
++;
15443 ffewhere_line_kill (instack
[indepth
].line
);
15444 ffewhere_column_kill (instack
[indepth
].column
);
15448 ffecom_decode_include_option (const char *dir
)
15450 if (! ignore_srcdir
&& !strcmp (dir
, "-"))
15454 struct file_name_list
*dirtmp
15455 = xmalloc (sizeof (struct file_name_list
));
15456 dirtmp
->next
= 0; /* New one goes on the end */
15457 dirtmp
->fname
= dir
;
15458 dirtmp
->got_name_map
= 0;
15459 append_include_chain (dirtmp
, dirtmp
);
15463 /* Open INCLUDEd file. */
15466 ffecom_open_include_ (char *name
, ffewhereLine l
, ffewhereColumn c
)
15469 size_t flen
= strlen (fbeg
);
15470 struct file_name_list
*search_start
= include
; /* Chain of dirs to search */
15471 struct file_name_list dsp
[1]; /* First in chain, if #include "..." */
15472 struct file_name_list
*searchptr
= 0;
15473 char *fname
; /* Dynamically allocated fname buffer */
15480 dsp
[0].fname
= NULL
;
15482 /* If -I- was specified, don't search current dir, only spec'd ones. */
15483 if (!ignore_srcdir
)
15485 for (fp
= &instack
[indepth
]; fp
>= instack
; fp
--)
15491 if ((nam
= fp
->nominal_fname
) != NULL
)
15493 /* Found a named file. Figure out dir of the file,
15494 and put it in front of the search list. */
15495 dsp
[0].next
= search_start
;
15496 search_start
= dsp
;
15498 ep
= strrchr (nam
, '/');
15499 #ifdef DIR_SEPARATOR
15500 if (ep
== NULL
) ep
= strrchr (nam
, DIR_SEPARATOR
);
15502 char *tmp
= strrchr (nam
, DIR_SEPARATOR
);
15503 if (tmp
!= NULL
&& tmp
> ep
) ep
= tmp
;
15507 ep
= strrchr (nam
, ']');
15508 if (ep
== NULL
) ep
= strrchr (nam
, '>');
15509 if (ep
== NULL
) ep
= strrchr (nam
, ':');
15510 if (ep
!= NULL
) ep
++;
15515 fname
= xmalloc (n
+ 1);
15516 strncpy (fname
, nam
, n
);
15518 dsp
[0].fname
= fname
;
15519 if (n
+ INCLUDE_LEN_FUDGE
> max_include_len
)
15520 max_include_len
= n
+ INCLUDE_LEN_FUDGE
;
15523 dsp
[0].fname
= NULL
; /* Current directory */
15524 dsp
[0].got_name_map
= 0;
15530 /* Allocate this permanently, because it gets stored in the definitions
15532 fname
= xmalloc (max_include_len
+ flen
+ 4);
15533 /* + 2 above for slash and terminating null. */
15534 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
15537 /* If specified file name is absolute, just open it. */
15540 #ifdef DIR_SEPARATOR
15541 || *fbeg
== DIR_SEPARATOR
15545 strncpy (fname
, (char *) fbeg
, flen
);
15547 f
= open_include_file (fname
, NULL
);
15553 /* Search directory path, trying to open the file.
15554 Copy each filename tried into FNAME. */
15556 for (searchptr
= search_start
; searchptr
; searchptr
= searchptr
->next
)
15558 if (searchptr
->fname
)
15560 /* The empty string in a search path is ignored.
15561 This makes it possible to turn off entirely
15562 a standard piece of the list. */
15563 if (searchptr
->fname
[0] == 0)
15565 strcpy (fname
, skip_redundant_dir_prefix (searchptr
->fname
));
15566 if (fname
[0] && fname
[strlen (fname
) - 1] != '/')
15567 strcat (fname
, "/");
15568 fname
[strlen (fname
) + flen
] = 0;
15573 strncat (fname
, fbeg
, flen
);
15575 /* Change this 1/2 Unix 1/2 VMS file specification into a
15576 full VMS file specification */
15577 if (searchptr
->fname
&& (searchptr
->fname
[0] != 0))
15579 /* Fix up the filename */
15580 hack_vms_include_specification (fname
);
15584 /* This is a normal VMS filespec, so use it unchanged. */
15585 strncpy (fname
, (char *) fbeg
, flen
);
15587 #if 0 /* Not for g77. */
15588 /* if it's '#include filename', add the missing .h */
15589 if (strchr (fname
, '.') == NULL
)
15590 strcat (fname
, ".h");
15594 f
= open_include_file (fname
, searchptr
);
15596 if (f
== NULL
&& errno
== EACCES
)
15598 print_containing_files (FFEBAD_severityWARNING
);
15599 /* xgettext:no-c-format */
15600 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
15601 FFEBAD_severityWARNING
);
15602 ffebad_string (fname
);
15603 ffebad_here (0, l
, c
);
15614 /* A file that was not found. */
15616 strncpy (fname
, (char *) fbeg
, flen
);
15618 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE
));
15619 ffebad_start (FFEBAD_OPEN_INCLUDE
);
15620 ffebad_here (0, l
, c
);
15621 ffebad_string (fname
);
15625 if (dsp
[0].fname
!= NULL
)
15626 free ((char *) dsp
[0].fname
);
15631 if (indepth
>= (INPUT_STACK_MAX
- 1))
15633 print_containing_files (FFEBAD_severityFATAL
);
15634 /* xgettext:no-c-format */
15635 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
15636 FFEBAD_severityFATAL
);
15637 ffebad_string (fname
);
15638 ffebad_here (0, l
, c
);
15643 instack
[indepth
].line
= ffewhere_line_use (l
);
15644 instack
[indepth
].column
= ffewhere_column_use (c
);
15646 fp
= &instack
[indepth
+ 1];
15647 memset (fp
, 0, sizeof (FILE_BUF
));
15648 fp
->nominal_fname
= fp
->fname
= fname
;
15649 fp
->dir
= searchptr
;
15652 input_file_stack_tick
++;
15657 /**INDENT* (Do not reformat this comment even with -fca option.)
15658 Data-gathering files: Given the source file listed below, compiled with
15659 f2c I obtained the output file listed after that, and from the output
15660 file I derived the above code.
15662 -------- (begin input file to f2c)
15668 double precision D1,D2
15670 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
15697 c FFEINTRIN_impACOS
15698 call fooR(ACOS(R1))
15699 c FFEINTRIN_impAIMAG
15700 call fooR(AIMAG(C1))
15701 c FFEINTRIN_impAINT
15702 call fooR(AINT(R1))
15703 c FFEINTRIN_impALOG
15704 call fooR(ALOG(R1))
15705 c FFEINTRIN_impALOG10
15706 call fooR(ALOG10(R1))
15707 c FFEINTRIN_impAMAX0
15708 call fooR(AMAX0(I1,I2))
15709 c FFEINTRIN_impAMAX1
15710 call fooR(AMAX1(R1,R2))
15711 c FFEINTRIN_impAMIN0
15712 call fooR(AMIN0(I1,I2))
15713 c FFEINTRIN_impAMIN1
15714 call fooR(AMIN1(R1,R2))
15715 c FFEINTRIN_impAMOD
15716 call fooR(AMOD(R1,R2))
15717 c FFEINTRIN_impANINT
15718 call fooR(ANINT(R1))
15719 c FFEINTRIN_impASIN
15720 call fooR(ASIN(R1))
15721 c FFEINTRIN_impATAN
15722 call fooR(ATAN(R1))
15723 c FFEINTRIN_impATAN2
15724 call fooR(ATAN2(R1,R2))
15725 c FFEINTRIN_impCABS
15726 call fooR(CABS(C1))
15727 c FFEINTRIN_impCCOS
15728 call fooC(CCOS(C1))
15729 c FFEINTRIN_impCEXP
15730 call fooC(CEXP(C1))
15731 c FFEINTRIN_impCHAR
15732 call fooA(CHAR(I1))
15733 c FFEINTRIN_impCLOG
15734 call fooC(CLOG(C1))
15735 c FFEINTRIN_impCONJG
15736 call fooC(CONJG(C1))
15739 c FFEINTRIN_impCOSH
15740 call fooR(COSH(R1))
15741 c FFEINTRIN_impCSIN
15742 call fooC(CSIN(C1))
15743 c FFEINTRIN_impCSQRT
15744 call fooC(CSQRT(C1))
15745 c FFEINTRIN_impDABS
15746 call fooD(DABS(D1))
15747 c FFEINTRIN_impDACOS
15748 call fooD(DACOS(D1))
15749 c FFEINTRIN_impDASIN
15750 call fooD(DASIN(D1))
15751 c FFEINTRIN_impDATAN
15752 call fooD(DATAN(D1))
15753 c FFEINTRIN_impDATAN2
15754 call fooD(DATAN2(D1,D2))
15755 c FFEINTRIN_impDCOS
15756 call fooD(DCOS(D1))
15757 c FFEINTRIN_impDCOSH
15758 call fooD(DCOSH(D1))
15759 c FFEINTRIN_impDDIM
15760 call fooD(DDIM(D1,D2))
15761 c FFEINTRIN_impDEXP
15762 call fooD(DEXP(D1))
15764 call fooR(DIM(R1,R2))
15765 c FFEINTRIN_impDINT
15766 call fooD(DINT(D1))
15767 c FFEINTRIN_impDLOG
15768 call fooD(DLOG(D1))
15769 c FFEINTRIN_impDLOG10
15770 call fooD(DLOG10(D1))
15771 c FFEINTRIN_impDMAX1
15772 call fooD(DMAX1(D1,D2))
15773 c FFEINTRIN_impDMIN1
15774 call fooD(DMIN1(D1,D2))
15775 c FFEINTRIN_impDMOD
15776 call fooD(DMOD(D1,D2))
15777 c FFEINTRIN_impDNINT
15778 call fooD(DNINT(D1))
15779 c FFEINTRIN_impDPROD
15780 call fooD(DPROD(R1,R2))
15781 c FFEINTRIN_impDSIGN
15782 call fooD(DSIGN(D1,D2))
15783 c FFEINTRIN_impDSIN
15784 call fooD(DSIN(D1))
15785 c FFEINTRIN_impDSINH
15786 call fooD(DSINH(D1))
15787 c FFEINTRIN_impDSQRT
15788 call fooD(DSQRT(D1))
15789 c FFEINTRIN_impDTAN
15790 call fooD(DTAN(D1))
15791 c FFEINTRIN_impDTANH
15792 call fooD(DTANH(D1))
15795 c FFEINTRIN_impIABS
15796 call fooI(IABS(I1))
15797 c FFEINTRIN_impICHAR
15798 call fooI(ICHAR(A1))
15799 c FFEINTRIN_impIDIM
15800 call fooI(IDIM(I1,I2))
15801 c FFEINTRIN_impIDNINT
15802 call fooI(IDNINT(D1))
15803 c FFEINTRIN_impINDEX
15804 call fooI(INDEX(A1,A2))
15805 c FFEINTRIN_impISIGN
15806 call fooI(ISIGN(I1,I2))
15810 call fooL(LGE(A1,A2))
15812 call fooL(LGT(A1,A2))
15814 call fooL(LLE(A1,A2))
15816 call fooL(LLT(A1,A2))
15817 c FFEINTRIN_impMAX0
15818 call fooI(MAX0(I1,I2))
15819 c FFEINTRIN_impMAX1
15820 call fooI(MAX1(R1,R2))
15821 c FFEINTRIN_impMIN0
15822 call fooI(MIN0(I1,I2))
15823 c FFEINTRIN_impMIN1
15824 call fooI(MIN1(R1,R2))
15826 call fooI(MOD(I1,I2))
15827 c FFEINTRIN_impNINT
15828 call fooI(NINT(R1))
15829 c FFEINTRIN_impSIGN
15830 call fooR(SIGN(R1,R2))
15833 c FFEINTRIN_impSINH
15834 call fooR(SINH(R1))
15835 c FFEINTRIN_impSQRT
15836 call fooR(SQRT(R1))
15839 c FFEINTRIN_impTANH
15840 call fooR(TANH(R1))
15841 c FFEINTRIN_imp_CMPLX_C
15842 call fooC(cmplx(C1,C2))
15843 c FFEINTRIN_imp_CMPLX_D
15844 call fooZ(cmplx(D1,D2))
15845 c FFEINTRIN_imp_CMPLX_I
15846 call fooC(cmplx(I1,I2))
15847 c FFEINTRIN_imp_CMPLX_R
15848 call fooC(cmplx(R1,R2))
15849 c FFEINTRIN_imp_DBLE_C
15850 call fooD(dble(C1))
15851 c FFEINTRIN_imp_DBLE_D
15852 call fooD(dble(D1))
15853 c FFEINTRIN_imp_DBLE_I
15854 call fooD(dble(I1))
15855 c FFEINTRIN_imp_DBLE_R
15856 call fooD(dble(R1))
15857 c FFEINTRIN_imp_INT_C
15859 c FFEINTRIN_imp_INT_D
15861 c FFEINTRIN_imp_INT_I
15863 c FFEINTRIN_imp_INT_R
15865 c FFEINTRIN_imp_REAL_C
15866 call fooR(real(C1))
15867 c FFEINTRIN_imp_REAL_D
15868 call fooR(real(D1))
15869 c FFEINTRIN_imp_REAL_I
15870 call fooR(real(I1))
15871 c FFEINTRIN_imp_REAL_R
15872 call fooR(real(R1))
15874 c FFEINTRIN_imp_INT_D:
15876 c FFEINTRIN_specIDINT
15877 call fooI(IDINT(D1))
15879 c FFEINTRIN_imp_INT_R:
15881 c FFEINTRIN_specIFIX
15882 call fooI(IFIX(R1))
15883 c FFEINTRIN_specINT
15886 c FFEINTRIN_imp_REAL_D:
15888 c FFEINTRIN_specSNGL
15889 call fooR(SNGL(D1))
15891 c FFEINTRIN_imp_REAL_I:
15893 c FFEINTRIN_specFLOAT
15894 call fooR(FLOAT(I1))
15895 c FFEINTRIN_specREAL
15896 call fooR(REAL(I1))
15899 -------- (end input file to f2c)
15901 -------- (begin output from providing above input file as input to:
15902 -------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
15903 -------- -e "s:^#.*$::g"')
15905 // -- translated by f2c (version 19950223).
15906 You must link the resulting object file with the libraries:
15907 -lf2c -lm (in that order)
15911 // f2c.h -- Standard Fortran to C header file //
15913 /// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
15915 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
15920 // F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
15921 // we assume short, float are OK //
15922 typedef long int // long int // integer;
15923 typedef char *address;
15924 typedef short int shortint;
15925 typedef float real;
15926 typedef double doublereal;
15927 typedef struct { real r, i; } complex;
15928 typedef struct { doublereal r, i; } doublecomplex;
15929 typedef long int // long int // logical;
15930 typedef short int shortlogical;
15931 typedef char logical1;
15932 typedef char integer1;
15933 // typedef long long longint; // // system-dependent //
15938 // Extern is for use with -E //
15952 typedef long int // int or long int // flag;
15953 typedef long int // int or long int // ftnlen;
15954 typedef long int // int or long int // ftnint;
15957 //external read, write//
15966 //internal read, write//
15996 //rewind, backspace, endfile//
16008 ftnint *inex; //parameters in standard's order//
16034 union Multitype { // for multiple entry points //
16045 typedef union Multitype Multitype;
16047 typedef long Long; // No longer used; formerly in Namelist //
16049 struct Vardesc { // for Namelist //
16055 typedef struct Vardesc Vardesc;
16062 typedef struct Namelist Namelist;
16071 // procedure parameter types for -A and -C++ //
16076 typedef int // Unknown procedure type // (*U_fp)();
16077 typedef shortint (*J_fp)();
16078 typedef integer (*I_fp)();
16079 typedef real (*R_fp)();
16080 typedef doublereal (*D_fp)(), (*E_fp)();
16081 typedef // Complex // void (*C_fp)();
16082 typedef // Double Complex // void (*Z_fp)();
16083 typedef logical (*L_fp)();
16084 typedef shortlogical (*K_fp)();
16085 typedef // Character // void (*H_fp)();
16086 typedef // Subroutine // int (*S_fp)();
16088 // E_fp is for real functions when -R is not specified //
16089 typedef void C_f; // complex function //
16090 typedef void H_f; // character function //
16091 typedef void Z_f; // double complex function //
16092 typedef doublereal E_f; // real function with -R not specified //
16094 // undef any lower-case symbols that your C compiler predefines, e.g.: //
16097 // (No such symbols should be defined in a strict ANSI C compiler.
16098 We can avoid trouble with f2c-translated code by using
16123 // Main program // MAIN__()
16125 // System generated locals //
16128 doublereal d__1, d__2;
16130 doublecomplex z__1, z__2, z__3;
16134 // Builtin functions //
16137 double pow_ri(), pow_di();
16141 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16142 asin(), atan(), atan2(), c_abs();
16143 void c_cos(), c_exp(), c_log(), r_cnjg();
16144 double cos(), cosh();
16145 void c_sin(), c_sqrt();
16146 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16147 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16148 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16149 logical l_ge(), l_gt(), l_le(), l_lt();
16153 // Local variables //
16154 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16155 fool_(), fooz_(), getem_();
16156 static char a1[10], a2[10];
16157 static complex c1, c2;
16158 static doublereal d1, d2;
16159 static integer i1, i2;
16160 static real r1, r2;
16163 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16171 d__1 = (doublereal) i1;
16172 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16182 c_div(&q__1, &c1, &c2);
16184 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16186 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16189 i__1 = pow_ii(&i1, &i2);
16191 r__1 = pow_ri(&r1, &i1);
16193 d__1 = pow_di(&d1, &i1);
16195 pow_ci(&q__1, &c1, &i1);
16197 d__1 = (doublereal) r1;
16198 d__2 = (doublereal) r2;
16199 r__1 = pow_dd(&d__1, &d__2);
16201 d__2 = (doublereal) r1;
16202 d__1 = pow_dd(&d__2, &d1);
16204 d__1 = pow_dd(&d1, &d2);
16206 d__2 = (doublereal) r1;
16207 d__1 = pow_dd(&d1, &d__2);
16209 z__2.r = c1.r, z__2.i = c1.i;
16210 z__3.r = c2.r, z__3.i = c2.i;
16211 pow_zz(&z__1, &z__2, &z__3);
16212 q__1.r = z__1.r, q__1.i = z__1.i;
16214 z__2.r = c1.r, z__2.i = c1.i;
16215 z__3.r = r1, z__3.i = 0.;
16216 pow_zz(&z__1, &z__2, &z__3);
16217 q__1.r = z__1.r, q__1.i = z__1.i;
16219 z__2.r = c1.r, z__2.i = c1.i;
16220 z__3.r = d1, z__3.i = 0.;
16221 pow_zz(&z__1, &z__2, &z__3);
16223 // FFEINTRIN_impABS //
16224 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
16226 // FFEINTRIN_impACOS //
16229 // FFEINTRIN_impAIMAG //
16230 r__1 = r_imag(&c1);
16232 // FFEINTRIN_impAINT //
16235 // FFEINTRIN_impALOG //
16238 // FFEINTRIN_impALOG10 //
16239 r__1 = r_lg10(&r1);
16241 // FFEINTRIN_impAMAX0 //
16242 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16244 // FFEINTRIN_impAMAX1 //
16245 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16247 // FFEINTRIN_impAMIN0 //
16248 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16250 // FFEINTRIN_impAMIN1 //
16251 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16253 // FFEINTRIN_impAMOD //
16254 r__1 = r_mod(&r1, &r2);
16256 // FFEINTRIN_impANINT //
16257 r__1 = r_nint(&r1);
16259 // FFEINTRIN_impASIN //
16262 // FFEINTRIN_impATAN //
16265 // FFEINTRIN_impATAN2 //
16266 r__1 = atan2(r1, r2);
16268 // FFEINTRIN_impCABS //
16271 // FFEINTRIN_impCCOS //
16274 // FFEINTRIN_impCEXP //
16277 // FFEINTRIN_impCHAR //
16278 *(unsigned char *)&ch__1[0] = i1;
16280 // FFEINTRIN_impCLOG //
16283 // FFEINTRIN_impCONJG //
16284 r_cnjg(&q__1, &c1);
16286 // FFEINTRIN_impCOS //
16289 // FFEINTRIN_impCOSH //
16292 // FFEINTRIN_impCSIN //
16295 // FFEINTRIN_impCSQRT //
16296 c_sqrt(&q__1, &c1);
16298 // FFEINTRIN_impDABS //
16299 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
16301 // FFEINTRIN_impDACOS //
16304 // FFEINTRIN_impDASIN //
16307 // FFEINTRIN_impDATAN //
16310 // FFEINTRIN_impDATAN2 //
16311 d__1 = atan2(d1, d2);
16313 // FFEINTRIN_impDCOS //
16316 // FFEINTRIN_impDCOSH //
16319 // FFEINTRIN_impDDIM //
16320 d__1 = d_dim(&d1, &d2);
16322 // FFEINTRIN_impDEXP //
16325 // FFEINTRIN_impDIM //
16326 r__1 = r_dim(&r1, &r2);
16328 // FFEINTRIN_impDINT //
16331 // FFEINTRIN_impDLOG //
16334 // FFEINTRIN_impDLOG10 //
16335 d__1 = d_lg10(&d1);
16337 // FFEINTRIN_impDMAX1 //
16338 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
16340 // FFEINTRIN_impDMIN1 //
16341 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
16343 // FFEINTRIN_impDMOD //
16344 d__1 = d_mod(&d1, &d2);
16346 // FFEINTRIN_impDNINT //
16347 d__1 = d_nint(&d1);
16349 // FFEINTRIN_impDPROD //
16350 d__1 = (doublereal) r1 * r2;
16352 // FFEINTRIN_impDSIGN //
16353 d__1 = d_sign(&d1, &d2);
16355 // FFEINTRIN_impDSIN //
16358 // FFEINTRIN_impDSINH //
16361 // FFEINTRIN_impDSQRT //
16364 // FFEINTRIN_impDTAN //
16367 // FFEINTRIN_impDTANH //
16370 // FFEINTRIN_impEXP //
16373 // FFEINTRIN_impIABS //
16374 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
16376 // FFEINTRIN_impICHAR //
16377 i__1 = *(unsigned char *)a1;
16379 // FFEINTRIN_impIDIM //
16380 i__1 = i_dim(&i1, &i2);
16382 // FFEINTRIN_impIDNINT //
16383 i__1 = i_dnnt(&d1);
16385 // FFEINTRIN_impINDEX //
16386 i__1 = i_indx(a1, a2, 10L, 10L);
16388 // FFEINTRIN_impISIGN //
16389 i__1 = i_sign(&i1, &i2);
16391 // FFEINTRIN_impLEN //
16392 i__1 = i_len(a1, 10L);
16394 // FFEINTRIN_impLGE //
16395 L__1 = l_ge(a1, a2, 10L, 10L);
16397 // FFEINTRIN_impLGT //
16398 L__1 = l_gt(a1, a2, 10L, 10L);
16400 // FFEINTRIN_impLLE //
16401 L__1 = l_le(a1, a2, 10L, 10L);
16403 // FFEINTRIN_impLLT //
16404 L__1 = l_lt(a1, a2, 10L, 10L);
16406 // FFEINTRIN_impMAX0 //
16407 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16409 // FFEINTRIN_impMAX1 //
16410 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16412 // FFEINTRIN_impMIN0 //
16413 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16415 // FFEINTRIN_impMIN1 //
16416 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16418 // FFEINTRIN_impMOD //
16421 // FFEINTRIN_impNINT //
16422 i__1 = i_nint(&r1);
16424 // FFEINTRIN_impSIGN //
16425 r__1 = r_sign(&r1, &r2);
16427 // FFEINTRIN_impSIN //
16430 // FFEINTRIN_impSINH //
16433 // FFEINTRIN_impSQRT //
16436 // FFEINTRIN_impTAN //
16439 // FFEINTRIN_impTANH //
16442 // FFEINTRIN_imp_CMPLX_C //
16445 q__1.r = r__1, q__1.i = r__2;
16447 // FFEINTRIN_imp_CMPLX_D //
16448 z__1.r = d1, z__1.i = d2;
16450 // FFEINTRIN_imp_CMPLX_I //
16453 q__1.r = r__1, q__1.i = r__2;
16455 // FFEINTRIN_imp_CMPLX_R //
16456 q__1.r = r1, q__1.i = r2;
16458 // FFEINTRIN_imp_DBLE_C //
16459 d__1 = (doublereal) c1.r;
16461 // FFEINTRIN_imp_DBLE_D //
16464 // FFEINTRIN_imp_DBLE_I //
16465 d__1 = (doublereal) i1;
16467 // FFEINTRIN_imp_DBLE_R //
16468 d__1 = (doublereal) r1;
16470 // FFEINTRIN_imp_INT_C //
16471 i__1 = (integer) c1.r;
16473 // FFEINTRIN_imp_INT_D //
16474 i__1 = (integer) d1;
16476 // FFEINTRIN_imp_INT_I //
16479 // FFEINTRIN_imp_INT_R //
16480 i__1 = (integer) r1;
16482 // FFEINTRIN_imp_REAL_C //
16485 // FFEINTRIN_imp_REAL_D //
16488 // FFEINTRIN_imp_REAL_I //
16491 // FFEINTRIN_imp_REAL_R //
16495 // FFEINTRIN_imp_INT_D: //
16497 // FFEINTRIN_specIDINT //
16498 i__1 = (integer) d1;
16501 // FFEINTRIN_imp_INT_R: //
16503 // FFEINTRIN_specIFIX //
16504 i__1 = (integer) r1;
16506 // FFEINTRIN_specINT //
16507 i__1 = (integer) r1;
16510 // FFEINTRIN_imp_REAL_D: //
16512 // FFEINTRIN_specSNGL //
16516 // FFEINTRIN_imp_REAL_I: //
16518 // FFEINTRIN_specFLOAT //
16521 // FFEINTRIN_specREAL //
16527 -------- (end output file from f2c)
16531 #include "gt-f-com.h"
16532 #include "gtype-f.h"