1 /* com.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4 Contributed by James Craig Burley.
6 This file is part of GNU Fortran.
8 GNU Fortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU Fortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Fortran; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 Contains compiler-specific functions.
32 /* Understanding this module means understanding the interface between
33 the g77 front end and the gcc back end (or, perhaps, some other
34 back end). In here are the functions called by the front end proper
35 to notify whatever back end is in place about certain things, and
36 also the back-end-specific functions. It's a bear to deal with, so
37 lately I've been trying to simplify things, especially with regard
38 to the gcc-back-end-specific stuff.
40 Building expressions generally seems quite easy, but building decls
41 has been challenging and is undergoing revision. gcc has several
44 TYPE_DECL -- a type (int, float, struct, function, etc.)
45 CONST_DECL -- a constant of some type other than function
46 LABEL_DECL -- a variable or a constant?
47 PARM_DECL -- an argument to a function (a variable that is a dummy)
48 RESULT_DECL -- the return value of a function (a variable)
49 VAR_DECL -- other variable (can hold a ptr-to-function, struct, int, etc.)
50 FUNCTION_DECL -- a function (either the actual function or an extern ref)
51 FIELD_DECL -- a field in a struct or union (goes into types)
53 g77 has a set of functions that somewhat parallels the gcc front end
54 when it comes to building decls:
56 Internal Function (one we define, not just declare as extern):
57 if (is_nested) push_f_function_context ();
58 start_function (get_identifier ("function_name"), function_type,
59 is_nested, is_public);
60 // for each arg, build PARM_DECL and call push_parm_decl (decl) with it;
61 store_parm_decls (is_main_program);
62 ffecom_start_compstmt ();
63 // for stmts and decls inside function, do appropriate things;
64 ffecom_end_compstmt ();
65 finish_function (is_nested);
66 if (is_nested) pop_f_function_context ();
71 // fill in external, public, static, &c for decl, and
72 // set DECL_INITIAL to error_mark_node if going to initialize
73 // set is_top_level TRUE only if not at top level and decl
74 // must go in top level (i.e. not within current function decl context)
75 d = start_decl (decl, is_top_level);
76 init = ...; // if have initializer
77 finish_decl (d, init, is_top_level);
89 #include "output.h" /* Must follow tree.h so TREE_CODE is defined! */
92 #include "diagnostic.h"
94 #include "langhooks.h"
95 #include "langhooks-def.h"
98 /* VMS-specific definitions */
101 #define O_RDONLY 0 /* Open arg for Read/Only */
102 #define O_WRONLY 1 /* Open arg for Write/Only */
103 #define read(fd,buf,size) VMS_read (fd,buf,size)
104 #define write(fd,buf,size) VMS_write (fd,buf,size)
105 #define open(fname,mode,prot) VMS_open (fname,mode,prot)
106 #define fopen(fname,mode) VMS_fopen (fname,mode)
107 #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
108 #define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
109 #define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
110 static int VMS_fstat (), VMS_stat ();
111 static char * VMS_strncat ();
112 static int VMS_read ();
113 static int VMS_write ();
114 static int VMS_open ();
115 static FILE * VMS_fopen ();
116 static FILE * VMS_freopen ();
117 static void hack_vms_include_specification ();
118 typedef struct { unsigned :16, :16, :16; } vms_ino_t
;
119 #define ino_t vms_ino_t
120 #define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
123 #define FFECOM_DETERMINE_TYPES 1 /* for com.h */
140 /* Externals defined here. */
142 /* Stream for reading from the input file. */
145 /* These definitions parallel those in c-decl.c so that code from that
146 module can be used pretty much as is. Much of these defs aren't
147 otherwise used, i.e. by g77 code per se, except some of them are used
148 to build some of them that are. The ones that are global (i.e. not
149 "static") are those that ste.c and such might use (directly
150 or by using com macros that reference them in their definitions). */
152 tree string_type_node
;
154 /* The rest of these are inventions for g77, though there might be
155 similar things in the C front end. As they are found, these
156 inventions should be renamed to be canonical. Note that only
157 the ones currently required to be global are so. */
159 static GTY(()) tree ffecom_tree_fun_type_void
;
161 tree ffecom_integer_type_node
; /* Abbrev for _tree_type[blah][blah]. */
162 tree ffecom_integer_zero_node
; /* Like *_*_* with g77's integer type. */
163 tree ffecom_integer_one_node
; /* " */
164 tree ffecom_tree_type
[FFEINFO_basictype
][FFEINFO_kindtype
];
166 /* _fun_type things are the f2c-specific versions. For -fno-f2c,
167 just use build_function_type and build_pointer_type on the
168 appropriate _tree_type array element. */
170 static GTY(()) tree ffecom_tree_fun_type
[FFEINFO_basictype
][FFEINFO_kindtype
];
172 ffecom_tree_ptr_to_fun_type
[FFEINFO_basictype
][FFEINFO_kindtype
];
173 static GTY(()) tree ffecom_tree_subr_type
;
174 static GTY(()) tree ffecom_tree_ptr_to_subr_type
;
175 static GTY(()) tree ffecom_tree_blockdata_type
;
177 static GTY(()) tree ffecom_tree_xargc_
;
179 ffecomSymbol ffecom_symbol_null_
188 ffeinfoKindtype ffecom_pointer_kind_
= FFEINFO_basictypeNONE
;
189 ffeinfoKindtype ffecom_label_kind_
= FFEINFO_basictypeNONE
;
191 int ffecom_f2c_typecode_
[FFEINFO_basictype
][FFEINFO_kindtype
];
192 tree ffecom_f2c_integer_type_node
;
193 static GTY(()) tree ffecom_f2c_ptr_to_integer_type_node
;
194 tree ffecom_f2c_address_type_node
;
195 tree ffecom_f2c_real_type_node
;
196 static GTY(()) tree ffecom_f2c_ptr_to_real_type_node
;
197 tree ffecom_f2c_doublereal_type_node
;
198 tree ffecom_f2c_complex_type_node
;
199 tree ffecom_f2c_doublecomplex_type_node
;
200 tree ffecom_f2c_longint_type_node
;
201 tree ffecom_f2c_logical_type_node
;
202 tree ffecom_f2c_flag_type_node
;
203 tree ffecom_f2c_ftnlen_type_node
;
204 tree ffecom_f2c_ftnlen_zero_node
;
205 tree ffecom_f2c_ftnlen_one_node
;
206 tree ffecom_f2c_ftnlen_two_node
;
207 tree ffecom_f2c_ptr_to_ftnlen_type_node
;
208 tree ffecom_f2c_ftnint_type_node
;
209 tree ffecom_f2c_ptr_to_ftnint_type_node
;
211 /* Simple definitions and enumerations. */
213 #ifndef FFECOM_sizeMAXSTACKITEM
214 #define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things
215 larger than this # bytes
216 off stack if possible. */
219 /* For systems that have large enough stacks, they should define
220 this to 0, and here, for ease of use later on, we just undefine
223 #if FFECOM_sizeMAXSTACKITEM == 0
224 #undef FFECOM_sizeMAXSTACKITEM
230 FFECOM_rttypeVOIDSTAR_
, /* C's `void *' type. */
231 FFECOM_rttypeFTNINT_
, /* f2c's `ftnint' type. */
232 FFECOM_rttypeINTEGER_
, /* f2c's `integer' type. */
233 FFECOM_rttypeLONGINT_
, /* f2c's `longint' type. */
234 FFECOM_rttypeLOGICAL_
, /* f2c's `logical' type. */
235 FFECOM_rttypeREAL_F2C_
, /* f2c's `real' returned as `double'. */
236 FFECOM_rttypeREAL_GNU_
, /* `real' returned as such. */
237 FFECOM_rttypeCOMPLEX_F2C_
, /* f2c's `complex' returned via 1st arg. */
238 FFECOM_rttypeCOMPLEX_GNU_
, /* f2c's `complex' returned directly. */
239 FFECOM_rttypeDOUBLE_
, /* C's `double' type. */
240 FFECOM_rttypeDOUBLEREAL_
, /* f2c's `doublereal' type. */
241 FFECOM_rttypeDBLCMPLX_F2C_
, /* f2c's `doublecomplex' returned via 1st arg. */
242 FFECOM_rttypeDBLCMPLX_GNU_
, /* f2c's `doublecomplex' returned directly. */
243 FFECOM_rttypeCHARACTER_
, /* f2c `char *'/`ftnlen' pair. */
247 /* Internal typedefs. */
249 typedef struct _ffecom_concat_list_ ffecomConcatList_
;
251 /* Private include files. */
254 /* Internal structure definitions. */
256 struct _ffecom_concat_list_
261 ffetargetCharacterSize minlen
;
262 ffetargetCharacterSize maxlen
;
265 /* Static functions (internal). */
267 static tree ffe_type_for_mode
PARAMS ((enum machine_mode
, int));
268 static tree ffe_type_for_size
PARAMS ((unsigned int, int));
269 static tree ffe_unsigned_type
PARAMS ((tree
));
270 static tree ffe_signed_type
PARAMS ((tree
));
271 static tree ffe_signed_or_unsigned_type
PARAMS ((int, tree
));
272 static bool ffe_mark_addressable
PARAMS ((tree
));
273 static tree ffe_truthvalue_conversion
PARAMS ((tree
));
274 static void ffecom_init_decl_processing
PARAMS ((void));
275 static tree
ffecom_arglist_expr_ (const char *argstring
, ffebld args
);
276 static tree
ffecom_widest_expr_type_ (ffebld list
);
277 static bool ffecom_overlap_ (tree dest_decl
, tree dest_offset
,
278 tree dest_size
, tree source_tree
,
279 ffebld source
, bool scalar_arg
);
280 static bool ffecom_args_overlapping_ (tree dest_tree
, ffebld dest
,
281 tree args
, tree callee_commons
,
283 static tree
ffecom_build_f2c_string_ (int i
, const char *s
);
284 static tree
ffecom_call_ (tree fn
, ffeinfoKindtype kt
,
285 bool is_f2c_complex
, tree type
,
286 tree args
, tree dest_tree
,
287 ffebld dest
, bool *dest_used
,
288 tree callee_commons
, bool scalar_args
, tree hook
);
289 static tree
ffecom_call_binop_ (tree fn
, ffeinfoKindtype kt
,
290 bool is_f2c_complex
, tree type
,
291 ffebld left
, ffebld right
,
292 tree dest_tree
, ffebld dest
,
293 bool *dest_used
, tree callee_commons
,
294 bool scalar_args
, bool ref
, tree hook
);
295 static void ffecom_char_args_x_ (tree
*xitem
, tree
*length
,
296 ffebld expr
, bool with_null
);
297 static tree
ffecom_check_size_overflow_ (ffesymbol s
, tree type
, bool dummy
);
298 static tree
ffecom_char_enhance_arg_ (tree
*xtype
, ffesymbol s
);
299 static ffecomConcatList_
300 ffecom_concat_list_gather_ (ffecomConcatList_ catlist
,
302 ffetargetCharacterSize max
);
303 static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist
);
304 static ffecomConcatList_
ffecom_concat_list_new_ (ffebld expr
,
305 ffetargetCharacterSize max
);
306 static void ffecom_debug_kludge_ (tree aggr
, const char *aggr_type
,
307 ffesymbol member
, tree member_type
,
308 ffetargetOffset offset
);
309 static void ffecom_do_entry_ (ffesymbol fn
, int entrynum
);
310 static tree
ffecom_expr_ (ffebld expr
, tree dest_tree
, ffebld dest
,
311 bool *dest_used
, bool assignp
, bool widenp
);
312 static tree
ffecom_expr_intrinsic_ (ffebld expr
, tree dest_tree
,
313 ffebld dest
, bool *dest_used
);
314 static tree
ffecom_expr_power_integer_ (ffebld expr
);
315 static void ffecom_expr_transform_ (ffebld expr
);
316 static void ffecom_f2c_make_type_ (tree
*type
, int tcode
, const char *name
);
317 static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt
, int size
,
319 static ffeglobal
ffecom_finish_global_ (ffeglobal global
);
320 static ffesymbol
ffecom_finish_symbol_transform_ (ffesymbol s
);
321 static tree
ffecom_get_appended_identifier_ (char us
, const char *text
);
322 static tree
ffecom_get_external_identifier_ (ffesymbol s
);
323 static tree
ffecom_get_identifier_ (const char *text
);
324 static tree
ffecom_gen_sfuncdef_ (ffesymbol s
,
327 static const char *ffecom_gfrt_args_ (ffecomGfrt ix
);
328 static tree
ffecom_gfrt_tree_ (ffecomGfrt ix
);
329 static tree
ffecom_init_zero_ (tree decl
);
330 static tree
ffecom_intrinsic_ichar_ (tree tree_type
, ffebld arg
,
332 static tree
ffecom_intrinsic_len_ (ffebld expr
);
333 static void ffecom_let_char_ (tree dest_tree
,
335 ffetargetCharacterSize dest_size
,
337 static void ffecom_make_gfrt_ (ffecomGfrt ix
);
338 static void ffecom_member_phase1_ (ffestorag mst
, ffestorag st
);
339 static void ffecom_member_phase2_ (ffestorag mst
, ffestorag st
);
340 static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size
,
342 static void ffecom_push_dummy_decls_ (ffebld dumlist
,
344 static void ffecom_start_progunit_ (void);
345 static ffesymbol
ffecom_sym_transform_ (ffesymbol s
);
346 static ffesymbol
ffecom_sym_transform_assign_ (ffesymbol s
);
347 static void ffecom_transform_common_ (ffesymbol s
);
348 static void ffecom_transform_equiv_ (ffestorag st
);
349 static tree
ffecom_transform_namelist_ (ffesymbol s
);
350 static void ffecom_tree_canonize_ptr_ (tree
*decl
, tree
*offset
,
352 static void ffecom_tree_canonize_ref_ (tree
*decl
, tree
*offset
,
353 tree
*size
, tree tree
);
354 static tree
ffecom_tree_divide_ (tree tree_type
, tree left
, tree right
,
355 tree dest_tree
, ffebld dest
,
356 bool *dest_used
, tree hook
);
357 static tree
ffecom_type_localvar_ (ffesymbol s
,
360 static tree
ffecom_type_namelist_ (void);
361 static tree
ffecom_type_vardesc_ (void);
362 static tree
ffecom_vardesc_ (ffebld expr
);
363 static tree
ffecom_vardesc_array_ (ffesymbol s
);
364 static tree
ffecom_vardesc_dims_ (ffesymbol s
);
365 static tree
ffecom_convert_narrow_ (tree type
, tree expr
);
366 static tree
ffecom_convert_widen_ (tree type
, tree expr
);
368 /* These are static functions that parallel those found in the C front
369 end and thus have the same names. */
371 static tree
bison_rule_compstmt_ (void);
372 static void bison_rule_pushlevel_ (void);
373 static void delete_block (tree block
);
374 static int duplicate_decls (tree newdecl
, tree olddecl
);
375 static void finish_decl (tree decl
, tree init
, bool is_top_level
);
376 static void finish_function (int nested
);
377 static const char *ffe_printable_name (tree decl
, int v
);
378 static void ffe_print_error_function (diagnostic_context
*, const char *);
379 static tree
lookup_name_current_level (tree name
);
380 static struct f_binding_level
*make_binding_level (void);
381 static void pop_f_function_context (void);
382 static void push_f_function_context (void);
383 static void push_parm_decl (tree parm
);
384 static tree
pushdecl_top_level (tree decl
);
385 static int kept_level_p (void);
386 static tree
storedecls (tree decls
);
387 static void store_parm_decls (int is_main_program
);
388 static tree
start_decl (tree decl
, bool is_top_level
);
389 static void start_function (tree name
, tree type
, int nested
, int public);
390 static void ffecom_file_ (const char *name
);
391 static void ffecom_close_include_ (FILE *f
);
392 static FILE *ffecom_open_include_ (char *name
, ffewhereLine l
,
395 /* Static objects accessed by functions in this module. */
397 static ffesymbol ffecom_primary_entry_
= NULL
;
398 static ffesymbol ffecom_nested_entry_
= NULL
;
399 static ffeinfoKind ffecom_primary_entry_kind_
;
400 static bool ffecom_primary_entry_is_proc_
;
401 static GTY(()) tree ffecom_outer_function_decl_
;
402 static GTY(()) tree ffecom_previous_function_decl_
;
403 static GTY(()) tree ffecom_which_entrypoint_decl_
;
404 static GTY(()) tree ffecom_float_zero_
;
405 static GTY(()) tree ffecom_float_half_
;
406 static GTY(()) tree ffecom_double_zero_
;
407 static GTY(()) tree ffecom_double_half_
;
408 static GTY(()) tree ffecom_func_result_
;/* For functions. */
409 static GTY(()) tree ffecom_func_length_
;/* For CHARACTER fns. */
410 static ffebld ffecom_list_blockdata_
;
411 static ffebld ffecom_list_common_
;
412 static ffebld ffecom_master_arglist_
;
413 static ffeinfoBasictype ffecom_master_bt_
;
414 static ffeinfoKindtype ffecom_master_kt_
;
415 static ffetargetCharacterSize ffecom_master_size_
;
416 static int ffecom_num_fns_
= 0;
417 static int ffecom_num_entrypoints_
= 0;
418 static bool ffecom_is_altreturning_
= FALSE
;
419 static GTY(()) tree ffecom_multi_type_node_
;
420 static GTY(()) tree ffecom_multi_retval_
;
422 ffecom_multi_fields_
[FFEINFO_basictype
][FFEINFO_kindtype
];
423 static bool ffecom_member_namelisted_
; /* _member_phase1_ namelisted? */
424 static bool ffecom_doing_entry_
= FALSE
;
425 static bool ffecom_transform_only_dummies_
= FALSE
;
426 static int ffecom_typesize_pointer_
;
427 static int ffecom_typesize_integer1_
;
429 /* Holds pointer-to-function expressions. */
431 static GTY(()) tree ffecom_gfrt_
[FFECOM_gfrt
];
433 /* Holds the external names of the functions. */
435 static const char *const ffecom_gfrt_name_
[FFECOM_gfrt
]
438 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NAME,
439 #include "com-rt.def"
443 /* Whether the function returns. */
445 static const bool ffecom_gfrt_volatile_
[FFECOM_gfrt
]
448 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) VOLATILE,
449 #include "com-rt.def"
453 /* Whether the function returns type complex. */
455 static const bool ffecom_gfrt_complex_
[FFECOM_gfrt
]
458 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) COMPLEX,
459 #include "com-rt.def"
463 /* Whether the function is const
464 (i.e., has no side effects and only depends on its arguments). */
466 static const bool ffecom_gfrt_const_
[FFECOM_gfrt
]
469 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) CONST,
470 #include "com-rt.def"
474 /* Type code for the function return value. */
476 static const ffecomRttype_ ffecom_gfrt_type_
[FFECOM_gfrt
]
479 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) TYPE,
480 #include "com-rt.def"
484 /* String of codes for the function's arguments. */
486 static const char *const ffecom_gfrt_argstring_
[FFECOM_gfrt
]
489 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) ARGS,
490 #include "com-rt.def"
494 /* Internal macros. */
496 /* We let tm.h override the types used here, to handle trivial differences
497 such as the choice of unsigned int or long unsigned int for size_t.
498 When machines start needing nontrivial differences in the size type,
499 it would be best to do something here to figure out automatically
500 from other information what type to use. */
503 #define SIZE_TYPE "long unsigned int"
506 #define ffecom_concat_list_count_(catlist) ((catlist).count)
507 #define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
508 #define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
509 #define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
511 #define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
512 #define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
514 /* For each binding contour we allocate a binding_level structure
515 * which records the names defined in that contour.
518 * 1) one for each function definition,
519 * where internal declarations of the parameters appear.
521 * The current meaning of a name can be found by searching the levels from
522 * the current one out to the global one.
525 /* Note that the information in the `names' component of the global contour
526 is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
528 struct f_binding_level
GTY(())
530 /* A chain of _DECL nodes for all variables, constants, functions,
531 and typedef types. These are in the reverse of the order supplied.
535 /* For each level (except not the global one),
536 a chain of BLOCK nodes for all the levels
537 that were entered and exited one level down. */
540 /* The BLOCK node for this level, if one has been preallocated.
541 If 0, the BLOCK is allocated (if needed) when the level is popped. */
544 /* The binding level which this one is contained in (inherits from). */
545 struct f_binding_level
*level_chain
;
547 /* 0: no ffecom_prepare_* functions called at this level yet;
548 1: ffecom_prepare* functions called, except not ffecom_prepare_end;
549 2: ffecom_prepare_end called. */
553 #define NULL_BINDING_LEVEL (struct f_binding_level *) NULL
555 /* The binding level currently in effect. */
557 static GTY(()) struct f_binding_level
*current_binding_level
;
559 /* A chain of binding_level structures awaiting reuse. */
561 static GTY((deletable (""))) struct f_binding_level
*free_binding_level
;
563 /* The outermost binding level, for names of file scope.
564 This is created when the compiler is started and exists
565 through the entire run. */
567 static struct f_binding_level
*global_binding_level
;
569 /* Binding level structures are initialized by copying this one. */
571 static const struct f_binding_level clear_binding_level
573 {NULL
, NULL
, NULL
, NULL_BINDING_LEVEL
, 0};
575 /* Language-dependent contents of an identifier. */
577 struct lang_identifier
GTY(())
579 struct tree_identifier common
;
586 /* Macros for access to language-specific slots in an identifier. */
587 /* Each of these slots contains a DECL node or null. */
589 /* This represents the value which the identifier has in the
590 file-scope namespace. */
591 #define IDENTIFIER_GLOBAL_VALUE(NODE) \
592 (((struct lang_identifier *)(NODE))->global_value)
593 /* This represents the value which the identifier has in the current
595 #define IDENTIFIER_LOCAL_VALUE(NODE) \
596 (((struct lang_identifier *)(NODE))->local_value)
597 /* This represents the value which the identifier has as a label in
598 the current label scope. */
599 #define IDENTIFIER_LABEL_VALUE(NODE) \
600 (((struct lang_identifier *)(NODE))->label_value)
601 /* This is nonzero if the identifier was "made up" by g77 code. */
602 #define IDENTIFIER_INVENTED(NODE) \
603 (((struct lang_identifier *)(NODE))->invented)
605 /* The resulting tree type. */
607 GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
608 chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
610 union tree_node
GTY ((tag ("0"),
611 desc ("tree_node_structure (&%h)")))
613 struct lang_identifier
GTY ((tag ("1"))) identifier
;
616 /* Fortran doesn't use either of these. */
617 struct lang_decl
GTY(())
620 struct lang_type
GTY(())
624 /* In identifiers, C uses the following fields in a special way:
625 TREE_PUBLIC to record that there was a previous local extern decl.
626 TREE_USED to record that such a decl was used.
627 TREE_ADDRESSABLE to record that the address of such a decl was used. */
629 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
630 that have names. Here so we can clear out their names' definitions
631 at the end of the function. */
633 static GTY(()) tree named_labels
;
635 /* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
637 static GTY(()) tree shadowed_labels
;
639 /* Return the subscript expression, modified to do range-checking.
641 `array' is the array to be checked against.
642 `element' is the subscript expression to check.
643 `dim' is the dimension number (starting at 0).
644 `total_dims' is the total number of dimensions (0 for CHARACTER substring).
648 ffecom_subscript_check_ (tree array
, tree element
, int dim
, int total_dims
,
649 const char *array_name
)
651 tree low
= TYPE_MIN_VALUE (TYPE_DOMAIN (array
));
652 tree high
= TYPE_MAX_VALUE (TYPE_DOMAIN (array
));
657 if (element
== error_mark_node
)
660 if (TREE_TYPE (low
) != TREE_TYPE (element
))
662 if (TYPE_PRECISION (TREE_TYPE (low
))
663 > TYPE_PRECISION (TREE_TYPE (element
)))
664 element
= convert (TREE_TYPE (low
), element
);
667 low
= convert (TREE_TYPE (element
), low
);
669 high
= convert (TREE_TYPE (element
), high
);
673 element
= ffecom_save_tree (element
);
676 /* Special handling for substring range checks. Fortran allows the
677 end subscript < begin subscript, which means that expressions like
678 string(1:0) are valid (and yield a null string). In view of this,
679 enforce two simpler conditions:
680 1) element<=high for end-substring;
681 2) element>=low for start-substring.
682 Run-time character movement will enforce remaining conditions.
684 More complicated checks would be better, but present structure only
685 provides one index element at a time, so it is not possible to
686 enforce a check of both i and j in string(i:j). If it were, the
687 complete set of rules would read,
688 if ( ((j<i) && ((low<=i<=high) || (low<=j<=high))) ||
689 ((low<=i<=high) && (low<=j<=high)) )
695 cond
= ffecom_2 (LE_EXPR
, integer_type_node
, element
, high
);
697 cond
= ffecom_2 (LE_EXPR
, integer_type_node
, low
, element
);
701 /* Array reference substring range checking. */
703 cond
= ffecom_2 (LE_EXPR
, integer_type_node
,
708 cond
= ffecom_2 (TRUTH_ANDIF_EXPR
, integer_type_node
,
710 ffecom_2 (LE_EXPR
, integer_type_node
,
728 var
= concat (array_name
, "[", (dim
? "end" : "start"),
729 "-substring]", NULL
);
730 len
= strlen (var
) + 1;
731 arg1
= build_string (len
, var
);
736 len
= strlen (array_name
) + 1;
737 arg1
= build_string (len
, array_name
);
741 var
= xmalloc (strlen (array_name
) + 40);
742 sprintf (var
, "%s[subscript-%d-of-%d]",
744 dim
+ 1, total_dims
);
745 len
= strlen (var
) + 1;
746 arg1
= build_string (len
, var
);
752 = build_type_variant (build_array_type (char_type_node
,
756 build_int_2 (len
, 0))),
758 TREE_CONSTANT (arg1
) = 1;
759 TREE_STATIC (arg1
) = 1;
760 arg1
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (arg1
)),
763 /* s_rnge adds one to the element to print it, so bias against
764 that -- want to print a faithful *subscript* value. */
765 arg2
= convert (ffecom_f2c_ftnint_type_node
,
766 ffecom_2 (MINUS_EXPR
,
769 convert (TREE_TYPE (element
),
772 proc
= concat (input_filename
, "/",
773 IDENTIFIER_POINTER (DECL_NAME (current_function_decl
)),
775 len
= strlen (proc
) + 1;
776 arg3
= build_string (len
, proc
);
781 = build_type_variant (build_array_type (char_type_node
,
785 build_int_2 (len
, 0))),
787 TREE_CONSTANT (arg3
) = 1;
788 TREE_STATIC (arg3
) = 1;
789 arg3
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (arg3
)),
792 arg4
= convert (ffecom_f2c_ftnint_type_node
,
793 build_int_2 (input_line
, 0));
795 arg1
= build_tree_list (NULL_TREE
, arg1
);
796 arg2
= build_tree_list (NULL_TREE
, arg2
);
797 arg3
= build_tree_list (NULL_TREE
, arg3
);
798 arg4
= build_tree_list (NULL_TREE
, arg4
);
799 TREE_CHAIN (arg3
) = arg4
;
800 TREE_CHAIN (arg2
) = arg3
;
801 TREE_CHAIN (arg1
) = arg2
;
805 die
= ffecom_call_gfrt (FFECOM_gfrtRANGE
,
807 TREE_SIDE_EFFECTS (die
) = 1;
808 die
= convert (void_type_node
, die
);
810 element
= ffecom_3 (COND_EXPR
,
819 /* Return the computed element of an array reference.
821 `item' is NULL_TREE, or the transformed pointer to the array.
822 `expr' is the original opARRAYREF expression, which is transformed
823 if `item' is NULL_TREE.
824 `want_ptr' is nonzero if a pointer to the element, instead of
825 the element itself, is to be returned. */
828 ffecom_arrayref_ (tree item
, ffebld expr
, int want_ptr
)
830 ffebld dims
[FFECOM_dimensionsMAX
];
833 int flatten
= ffe_is_flatten_arrays ();
839 const char *array_name
;
843 if (ffebld_op (ffebld_left (expr
)) == FFEBLD_opSYMTER
)
844 array_name
= ffesymbol_text (ffebld_symter (ffebld_left (expr
)));
846 array_name
= "[expr?]";
848 /* Build up ARRAY_REFs in reverse order (since we're column major
849 here in Fortran land). */
851 for (i
= 0, list
= ffebld_right (expr
);
853 ++i
, list
= ffebld_trail (list
))
855 dims
[i
] = ffebld_head (list
);
856 type
= ffeinfo_type (ffebld_basictype (dims
[i
]),
857 ffebld_kindtype (dims
[i
]));
859 && ffecom_typesize_pointer_
> ffecom_typesize_integer1_
860 && ffetype_size (type
) > ffecom_typesize_integer1_
)
861 /* E.g. ARRAY(INDEX), given INTEGER*8 INDEX, on a system with 64-bit
862 pointers and 32-bit integers. Do the full 64-bit pointer
863 arithmetic, for codes using arrays for nonstandard heap-like
870 need_ptr
= want_ptr
|| flatten
;
875 item
= ffecom_ptr_to_expr (ffebld_left (expr
));
877 item
= ffecom_expr (ffebld_left (expr
));
879 if (item
== error_mark_node
)
882 if (ffeinfo_where (ffebld_info (expr
)) == FFEINFO_whereFLEETING
883 && ! ffe_mark_addressable (item
))
884 return error_mark_node
;
887 if (item
== error_mark_node
)
894 for (--i
, array
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item
)));
896 --i
, array
= TYPE_MAIN_VARIANT (TREE_TYPE (array
)))
898 min
= TYPE_MIN_VALUE (TYPE_DOMAIN (array
));
899 element
= ffecom_expr_ (dims
[i
], NULL
, NULL
, NULL
, FALSE
, TRUE
);
900 if (flag_bounds_check
)
901 element
= ffecom_subscript_check_ (array
, element
, i
, total_dims
,
903 if (element
== error_mark_node
)
906 /* Widen integral arithmetic as desired while preserving
908 tree_type
= TREE_TYPE (element
);
909 tree_type_x
= tree_type
;
911 && GET_MODE_CLASS (TYPE_MODE (tree_type
)) == MODE_INT
912 && TYPE_PRECISION (tree_type
) < TYPE_PRECISION (sizetype
))
913 tree_type_x
= (TREE_UNSIGNED (tree_type
) ? usizetype
: ssizetype
);
915 if (TREE_TYPE (min
) != tree_type_x
)
916 min
= convert (tree_type_x
, min
);
917 if (TREE_TYPE (element
) != tree_type_x
)
918 element
= convert (tree_type_x
, element
);
920 item
= ffecom_2 (PLUS_EXPR
,
921 build_pointer_type (TREE_TYPE (array
)),
923 size_binop (MULT_EXPR
,
924 size_in_bytes (TREE_TYPE (array
)),
926 fold (build (MINUS_EXPR
,
932 item
= ffecom_1 (INDIRECT_REF
,
933 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item
))),
943 array
= TYPE_MAIN_VARIANT (TREE_TYPE (item
));
945 element
= ffecom_expr_ (dims
[i
], NULL
, NULL
, NULL
, FALSE
, TRUE
);
946 if (flag_bounds_check
)
947 element
= ffecom_subscript_check_ (array
, element
, i
, total_dims
,
949 if (element
== error_mark_node
)
952 /* Widen integral arithmetic as desired while preserving
954 tree_type
= TREE_TYPE (element
);
955 tree_type_x
= tree_type
;
957 && GET_MODE_CLASS (TYPE_MODE (tree_type
)) == MODE_INT
958 && TYPE_PRECISION (tree_type
) < TYPE_PRECISION (sizetype
))
959 tree_type_x
= (TREE_UNSIGNED (tree_type
) ? usizetype
: ssizetype
);
961 element
= convert (tree_type_x
, element
);
963 item
= ffecom_2 (ARRAY_REF
,
964 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item
))),
973 /* This is like gcc's stabilize_reference -- in fact, most of the code
974 comes from that -- but it handles the situation where the reference
975 is going to have its subparts picked at, and it shouldn't change
976 (or trigger extra invocations of functions in the subtrees) due to
977 this. save_expr is a bit overzealous, because we don't need the
978 entire thing calculated and saved like a temp. So, for DECLs, no
979 change is needed, because these are stable aggregates, and ARRAY_REF
980 and such might well be stable too, but for things like calculations,
981 we do need to calculate a snapshot of a value before picking at it. */
984 ffecom_stabilize_aggregate_ (tree ref
)
987 enum tree_code code
= TREE_CODE (ref
);
994 /* No action is needed in this case. */
1000 case FIX_TRUNC_EXPR
:
1001 case FIX_FLOOR_EXPR
:
1002 case FIX_ROUND_EXPR
:
1004 result
= build_nt (code
, stabilize_reference (TREE_OPERAND (ref
, 0)));
1008 result
= build_nt (INDIRECT_REF
,
1009 stabilize_reference_1 (TREE_OPERAND (ref
, 0)));
1013 result
= build_nt (COMPONENT_REF
,
1014 stabilize_reference (TREE_OPERAND (ref
, 0)),
1015 TREE_OPERAND (ref
, 1));
1019 result
= build_nt (BIT_FIELD_REF
,
1020 stabilize_reference (TREE_OPERAND (ref
, 0)),
1021 stabilize_reference_1 (TREE_OPERAND (ref
, 1)),
1022 stabilize_reference_1 (TREE_OPERAND (ref
, 2)));
1026 result
= build_nt (ARRAY_REF
,
1027 stabilize_reference (TREE_OPERAND (ref
, 0)),
1028 stabilize_reference_1 (TREE_OPERAND (ref
, 1)));
1032 result
= build_nt (COMPOUND_EXPR
,
1033 stabilize_reference_1 (TREE_OPERAND (ref
, 0)),
1034 stabilize_reference (TREE_OPERAND (ref
, 1)));
1042 return save_expr (ref
);
1045 return error_mark_node
;
1048 TREE_TYPE (result
) = TREE_TYPE (ref
);
1049 TREE_READONLY (result
) = TREE_READONLY (ref
);
1050 TREE_SIDE_EFFECTS (result
) = TREE_SIDE_EFFECTS (ref
);
1051 TREE_THIS_VOLATILE (result
) = TREE_THIS_VOLATILE (ref
);
1056 /* A rip-off of gcc's convert.c convert_to_complex function,
1057 reworked to handle complex implemented as C structures
1058 (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */
1061 ffecom_convert_to_complex_ (tree type
, tree expr
)
1063 register enum tree_code form
= TREE_CODE (TREE_TYPE (expr
));
1066 assert (TREE_CODE (type
) == RECORD_TYPE
);
1068 subtype
= TREE_TYPE (TYPE_FIELDS (type
));
1070 if (form
== REAL_TYPE
|| form
== INTEGER_TYPE
|| form
== ENUMERAL_TYPE
)
1072 expr
= convert (subtype
, expr
);
1073 return ffecom_2 (COMPLEX_EXPR
, type
, expr
,
1074 convert (subtype
, integer_zero_node
));
1077 if (form
== RECORD_TYPE
)
1079 tree elt_type
= TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr
)));
1080 if (TYPE_MAIN_VARIANT (elt_type
) == TYPE_MAIN_VARIANT (subtype
))
1084 expr
= save_expr (expr
);
1085 return ffecom_2 (COMPLEX_EXPR
,
1088 ffecom_1 (REALPART_EXPR
,
1089 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr
))),
1092 ffecom_1 (IMAGPART_EXPR
,
1093 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr
))),
1098 if (form
== POINTER_TYPE
|| form
== REFERENCE_TYPE
)
1099 error ("pointer value used where a complex was expected");
1101 error ("aggregate value used where a complex was expected");
1103 return ffecom_2 (COMPLEX_EXPR
, type
,
1104 convert (subtype
, integer_zero_node
),
1105 convert (subtype
, integer_zero_node
));
1108 /* Like gcc's convert(), but crashes if widening might happen. */
1111 ffecom_convert_narrow_ (tree type
, tree expr
)
1113 register tree e
= expr
;
1114 register enum tree_code code
= TREE_CODE (type
);
1116 if (type
== TREE_TYPE (e
)
1117 || TREE_CODE (e
) == ERROR_MARK
)
1119 if (TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (TREE_TYPE (e
)))
1120 return fold (build1 (NOP_EXPR
, type
, e
));
1121 if (TREE_CODE (TREE_TYPE (e
)) == ERROR_MARK
1122 || code
== ERROR_MARK
)
1123 return error_mark_node
;
1124 if (TREE_CODE (TREE_TYPE (e
)) == VOID_TYPE
)
1126 assert ("void value not ignored as it ought to be" == NULL
);
1127 return error_mark_node
;
1129 assert (code
!= VOID_TYPE
);
1130 if ((code
!= RECORD_TYPE
)
1131 && (TREE_CODE (TREE_TYPE (e
)) == RECORD_TYPE
))
1132 assert ("converting COMPLEX to REAL" == NULL
);
1133 assert (code
!= ENUMERAL_TYPE
);
1134 if (code
== INTEGER_TYPE
)
1136 assert ((TREE_CODE (TREE_TYPE (e
)) == INTEGER_TYPE
1137 && TYPE_PRECISION (type
) <= TYPE_PRECISION (TREE_TYPE (e
)))
1138 || (TREE_CODE (TREE_TYPE (e
)) == POINTER_TYPE
1139 && (TYPE_PRECISION (type
)
1140 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e
))))));
1141 return fold (convert_to_integer (type
, e
));
1143 if (code
== POINTER_TYPE
)
1145 assert (TREE_CODE (TREE_TYPE (e
)) == POINTER_TYPE
);
1146 return fold (convert_to_pointer (type
, e
));
1148 if (code
== REAL_TYPE
)
1150 assert (TREE_CODE (TREE_TYPE (e
)) == REAL_TYPE
);
1151 assert (TYPE_PRECISION (type
) <= TYPE_PRECISION (TREE_TYPE (e
)));
1152 return fold (convert_to_real (type
, e
));
1154 if (code
== COMPLEX_TYPE
)
1156 assert (TREE_CODE (TREE_TYPE (e
)) == COMPLEX_TYPE
);
1157 assert (TYPE_PRECISION (TREE_TYPE (type
)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e
))));
1158 return fold (convert_to_complex (type
, e
));
1160 if (code
== RECORD_TYPE
)
1162 assert (TREE_CODE (TREE_TYPE (e
)) == RECORD_TYPE
);
1163 /* Check that at least the first field name agrees. */
1164 assert (DECL_NAME (TYPE_FIELDS (type
))
1165 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e
))));
1166 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type
)))
1167 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e
)))));
1168 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type
)))
1169 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e
)))))
1171 return fold (ffecom_convert_to_complex_ (type
, e
));
1174 assert ("conversion to non-scalar type requested" == NULL
);
1175 return error_mark_node
;
1178 /* Like gcc's convert(), but crashes if narrowing might happen. */
1181 ffecom_convert_widen_ (tree type
, tree expr
)
1183 register tree e
= expr
;
1184 register enum tree_code code
= TREE_CODE (type
);
1186 if (type
== TREE_TYPE (e
)
1187 || TREE_CODE (e
) == ERROR_MARK
)
1189 if (TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (TREE_TYPE (e
)))
1190 return fold (build1 (NOP_EXPR
, type
, e
));
1191 if (TREE_CODE (TREE_TYPE (e
)) == ERROR_MARK
1192 || code
== ERROR_MARK
)
1193 return error_mark_node
;
1194 if (TREE_CODE (TREE_TYPE (e
)) == VOID_TYPE
)
1196 assert ("void value not ignored as it ought to be" == NULL
);
1197 return error_mark_node
;
1199 assert (code
!= VOID_TYPE
);
1200 if ((code
!= RECORD_TYPE
)
1201 && (TREE_CODE (TREE_TYPE (e
)) == RECORD_TYPE
))
1202 assert ("narrowing COMPLEX to REAL" == NULL
);
1203 assert (code
!= ENUMERAL_TYPE
);
1204 if (code
== INTEGER_TYPE
)
1206 assert ((TREE_CODE (TREE_TYPE (e
)) == INTEGER_TYPE
1207 && TYPE_PRECISION (type
) >= TYPE_PRECISION (TREE_TYPE (e
)))
1208 || (TREE_CODE (TREE_TYPE (e
)) == POINTER_TYPE
1209 && (TYPE_PRECISION (type
)
1210 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e
))))));
1211 return fold (convert_to_integer (type
, e
));
1213 if (code
== POINTER_TYPE
)
1215 assert (TREE_CODE (TREE_TYPE (e
)) == POINTER_TYPE
);
1216 return fold (convert_to_pointer (type
, e
));
1218 if (code
== REAL_TYPE
)
1220 assert (TREE_CODE (TREE_TYPE (e
)) == REAL_TYPE
);
1221 assert (TYPE_PRECISION (type
) >= TYPE_PRECISION (TREE_TYPE (e
)));
1222 return fold (convert_to_real (type
, e
));
1224 if (code
== COMPLEX_TYPE
)
1226 assert (TREE_CODE (TREE_TYPE (e
)) == COMPLEX_TYPE
);
1227 assert (TYPE_PRECISION (TREE_TYPE (type
)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e
))));
1228 return fold (convert_to_complex (type
, e
));
1230 if (code
== RECORD_TYPE
)
1232 assert (TREE_CODE (TREE_TYPE (e
)) == RECORD_TYPE
);
1233 /* Check that at least the first field name agrees. */
1234 assert (DECL_NAME (TYPE_FIELDS (type
))
1235 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e
))));
1236 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type
)))
1237 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e
)))));
1238 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type
)))
1239 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e
)))))
1241 return fold (ffecom_convert_to_complex_ (type
, e
));
1244 assert ("conversion to non-scalar type requested" == NULL
);
1245 return error_mark_node
;
1248 /* Handles making a COMPLEX type, either the standard
1249 (but buggy?) gbe way, or the safer (but less elegant?)
1253 ffecom_make_complex_type_ (tree subtype
)
1259 if (ffe_is_emulate_complex ())
1261 type
= make_node (RECORD_TYPE
);
1262 realfield
= ffecom_decl_field (type
, NULL_TREE
, "r", subtype
);
1263 imagfield
= ffecom_decl_field (type
, realfield
, "i", subtype
);
1264 TYPE_FIELDS (type
) = realfield
;
1269 type
= make_node (COMPLEX_TYPE
);
1270 TREE_TYPE (type
) = subtype
;
1277 /* Chooses either the gbe or the f2c way to build a
1278 complex constant. */
1281 ffecom_build_complex_constant_ (tree type
, tree realpart
, tree imagpart
)
1285 if (ffe_is_emulate_complex ())
1287 bothparts
= build_tree_list (TYPE_FIELDS (type
), realpart
);
1288 TREE_CHAIN (bothparts
) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type
)), imagpart
);
1289 bothparts
= build_constructor (type
, bothparts
);
1293 bothparts
= build_complex (type
, realpart
, imagpart
);
1300 ffecom_arglist_expr_ (const char *c
, ffebld expr
)
1303 tree
*plist
= &list
;
1304 tree trail
= NULL_TREE
; /* Append char length args here. */
1305 tree
*ptrail
= &trail
;
1310 tree wanted
= NULL_TREE
;
1311 static const char zed
[] = "0";
1316 while (expr
!= NULL
)
1339 wanted
= ffecom_f2c_complex_type_node
;
1343 wanted
= ffecom_f2c_doublereal_type_node
;
1347 wanted
= ffecom_f2c_doublecomplex_type_node
;
1351 wanted
= ffecom_f2c_real_type_node
;
1355 wanted
= ffecom_f2c_integer_type_node
;
1359 wanted
= ffecom_f2c_longint_type_node
;
1363 assert ("bad argstring code" == NULL
);
1369 exprh
= ffebld_head (expr
);
1373 if ((wanted
== NULL_TREE
)
1376 (ffecom_tree_type
[ffeinfo_basictype (ffebld_info (exprh
))]
1377 [ffeinfo_kindtype (ffebld_info (exprh
))])
1378 == TYPE_MODE (wanted
))))
1380 = build_tree_list (NULL_TREE
,
1381 ffecom_arg_ptr_to_expr (exprh
,
1385 item
= ffecom_arg_expr (exprh
, &length
);
1386 item
= ffecom_convert_widen_ (wanted
, item
);
1389 item
= ffecom_1 (ADDR_EXPR
,
1390 build_pointer_type (TREE_TYPE (item
)),
1394 = build_tree_list (NULL_TREE
,
1398 plist
= &TREE_CHAIN (*plist
);
1399 expr
= ffebld_trail (expr
);
1400 if (length
!= NULL_TREE
)
1402 *ptrail
= build_tree_list (NULL_TREE
, length
);
1403 ptrail
= &TREE_CHAIN (*ptrail
);
1407 /* We've run out of args in the call; if the implementation expects
1408 more, supply null pointers for them, which the implementation can
1409 check to see if an arg was omitted. */
1411 while (*c
!= '\0' && *c
!= '0')
1416 assert ("missing arg to run-time routine!" == NULL
);
1431 assert ("bad arg string code" == NULL
);
1435 = build_tree_list (NULL_TREE
,
1437 plist
= &TREE_CHAIN (*plist
);
1446 ffecom_widest_expr_type_ (ffebld list
)
1449 ffebld widest
= NULL
;
1451 ffetype widest_type
= NULL
;
1454 for (; list
!= NULL
; list
= ffebld_trail (list
))
1456 item
= ffebld_head (list
);
1459 if ((widest
!= NULL
)
1460 && (ffeinfo_basictype (ffebld_info (item
))
1461 != ffeinfo_basictype (ffebld_info (widest
))))
1463 type
= ffeinfo_type (ffeinfo_basictype (ffebld_info (item
)),
1464 ffeinfo_kindtype (ffebld_info (item
)));
1465 if ((widest
== FFEINFO_kindtypeNONE
)
1466 || (ffetype_size (type
)
1467 > ffetype_size (widest_type
)))
1474 assert (widest
!= NULL
);
1475 t
= ffecom_tree_type
[ffeinfo_basictype (ffebld_info (widest
))]
1476 [ffeinfo_kindtype (ffebld_info (widest
))];
1477 assert (t
!= NULL_TREE
);
1481 /* Check whether a partial overlap between two expressions is possible.
1483 Can *starting* to write a portion of expr1 change the value
1484 computed (perhaps already, *partially*) by expr2?
1486 Currently, this is a concern only for a COMPLEX expr1. But if it
1487 isn't in COMMON or local EQUIVALENCE, since we don't support
1488 aliasing of arguments, it isn't a concern. */
1491 ffecom_possible_partial_overlap_ (ffebld expr1
, ffebld expr2 ATTRIBUTE_UNUSED
)
1496 switch (ffebld_op (expr1
))
1498 case FFEBLD_opSYMTER
:
1499 sym
= ffebld_symter (expr1
);
1502 case FFEBLD_opARRAYREF
:
1503 if (ffebld_op (ffebld_left (expr1
)) != FFEBLD_opSYMTER
)
1505 sym
= ffebld_symter (ffebld_left (expr1
));
1512 if (ffesymbol_where (sym
) != FFEINFO_whereCOMMON
1513 && (ffesymbol_where (sym
) != FFEINFO_whereLOCAL
1514 || ! (st
= ffesymbol_storage (sym
))
1515 || ! ffestorag_parent (st
)))
1518 /* It's in COMMON or local EQUIVALENCE. */
1523 /* Check whether dest and source might overlap. ffebld versions of these
1524 might or might not be passed, will be NULL if not.
1526 The test is really whether source_tree is modifiable and, if modified,
1527 might overlap destination such that the value(s) in the destination might
1528 change before it is finally modified. dest_* are the canonized
1529 destination itself. */
1532 ffecom_overlap_ (tree dest_decl
, tree dest_offset
, tree dest_size
,
1533 tree source_tree
, ffebld source UNUSED
,
1541 if (source_tree
== NULL_TREE
)
1544 switch (TREE_CODE (source_tree
))
1547 case IDENTIFIER_NODE
:
1558 case TRUNC_DIV_EXPR
:
1560 case FLOOR_DIV_EXPR
:
1561 case ROUND_DIV_EXPR
:
1562 case TRUNC_MOD_EXPR
:
1564 case FLOOR_MOD_EXPR
:
1565 case ROUND_MOD_EXPR
:
1567 case EXACT_DIV_EXPR
:
1568 case FIX_TRUNC_EXPR
:
1570 case FIX_FLOOR_EXPR
:
1571 case FIX_ROUND_EXPR
:
1585 case BIT_ANDTC_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
,
1716 tree args
, tree callee_commons
,
1724 ffecom_tree_canonize_ref_ (&dest_decl
, &dest_offset
, &dest_size
,
1727 if (dest_decl
== NULL_TREE
)
1728 return FALSE
; /* Seems unlikely! */
1730 /* If the decl cannot be determined reliably, or if its in COMMON
1731 and the callee isn't known to not futz with COMMON via other
1732 means, overlap might happen. */
1734 if ((TREE_CODE (dest_decl
) == ERROR_MARK
)
1735 || ((callee_commons
!= NULL_TREE
)
1736 && TREE_PUBLIC (dest_decl
)))
1739 for (; args
!= NULL_TREE
; args
= TREE_CHAIN (args
))
1741 if (((arg
= TREE_VALUE (args
)) != NULL_TREE
)
1742 && ffecom_overlap_ (dest_decl
, dest_offset
, dest_size
,
1743 arg
, NULL
, scalar_args
))
1750 /* Build a string for a variable name as used by NAMELIST. This means that
1751 if we're using the f2c library, we build an uppercase string, since
1755 ffecom_build_f2c_string_ (int i
, const char *s
)
1757 if (!ffe_is_f2c_library ())
1758 return build_string (i
, s
);
1767 if (((size_t) i
) > ARRAY_SIZE (space
))
1768 tmp
= malloc_new_ks (malloc_pool_image (), "f2c_string", i
);
1772 for (p
= s
, q
= tmp
; *p
!= '\0'; ++p
, ++q
)
1776 t
= build_string (i
, tmp
);
1778 if (((size_t) i
) > ARRAY_SIZE (space
))
1779 malloc_kill_ks (malloc_pool_image (), tmp
, i
);
1785 /* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for
1786 type to just get whatever the function returns), handling the
1787 f2c value-returning convention, if required, by prepending
1788 to the arglist a pointer to a temporary to receive the return value. */
1791 ffecom_call_ (tree fn
, ffeinfoKindtype kt
, bool is_f2c_complex
,
1792 tree type
, tree args
, tree dest_tree
,
1793 ffebld dest
, bool *dest_used
, tree callee_commons
,
1794 bool scalar_args
, tree hook
)
1799 if (dest_used
!= NULL
)
1804 if ((dest_used
== NULL
)
1806 || (ffeinfo_basictype (ffebld_info (dest
))
1807 != FFEINFO_basictypeCOMPLEX
)
1808 || (ffeinfo_kindtype (ffebld_info (dest
)) != kt
)
1809 || ((type
!= NULL_TREE
) && (TREE_TYPE (dest_tree
) != type
))
1810 || ffecom_args_overlapping_ (dest_tree
, dest
, args
,
1820 tempvar
= dest_tree
;
1825 = build_tree_list (NULL_TREE
,
1826 ffecom_1 (ADDR_EXPR
,
1827 build_pointer_type (TREE_TYPE (tempvar
)),
1829 TREE_CHAIN (item
) = args
;
1831 item
= ffecom_3s (CALL_EXPR
, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn
))), fn
,
1834 if (tempvar
!= dest_tree
)
1835 item
= ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (tempvar
), item
, tempvar
);
1838 item
= ffecom_3s (CALL_EXPR
, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn
))), fn
,
1841 if ((type
!= NULL_TREE
) && (TREE_TYPE (item
) != type
))
1842 item
= ffecom_convert_narrow_ (type
, item
);
1847 /* Given two arguments, transform them and make a call to the given
1848 function via ffecom_call_. */
1851 ffecom_call_binop_ (tree fn
, ffeinfoKindtype kt
, bool is_f2c_complex
,
1852 tree type
, ffebld left
, ffebld right
,
1853 tree dest_tree
, ffebld dest
, bool *dest_used
,
1854 tree callee_commons
, bool scalar_args
, bool ref
, tree hook
)
1863 /* Pass arguments by reference. */
1864 left_tree
= ffecom_arg_ptr_to_expr (left
, &left_length
);
1865 right_tree
= ffecom_arg_ptr_to_expr (right
, &right_length
);
1869 /* Pass arguments by value. */
1870 left_tree
= ffecom_arg_expr (left
, &left_length
);
1871 right_tree
= ffecom_arg_expr (right
, &right_length
);
1875 left_tree
= build_tree_list (NULL_TREE
, left_tree
);
1876 right_tree
= build_tree_list (NULL_TREE
, right_tree
);
1877 TREE_CHAIN (left_tree
) = right_tree
;
1879 if (left_length
!= NULL_TREE
)
1881 left_length
= build_tree_list (NULL_TREE
, left_length
);
1882 TREE_CHAIN (right_tree
) = left_length
;
1885 if (right_length
!= NULL_TREE
)
1887 right_length
= build_tree_list (NULL_TREE
, right_length
);
1888 if (left_length
!= NULL_TREE
)
1889 TREE_CHAIN (left_length
) = right_length
;
1891 TREE_CHAIN (right_tree
) = right_length
;
1894 return ffecom_call_ (fn
, kt
, is_f2c_complex
, type
, left_tree
,
1895 dest_tree
, dest
, dest_used
, callee_commons
,
1899 /* Return ptr/length args for char subexpression
1901 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
1902 subexpressions by constructing the appropriate trees for the ptr-to-
1903 character-text and length-of-character-text arguments in a calling
1906 Note that if with_null is TRUE, and the expression is an opCONTER,
1907 a null byte is appended to the string. */
1910 ffecom_char_args_x_ (tree
*xitem
, tree
*length
, ffebld expr
, bool with_null
)
1914 ffetargetCharacter1 val
;
1915 ffetargetCharacterSize newlen
;
1917 switch (ffebld_op (expr
))
1919 case FFEBLD_opCONTER
:
1920 val
= ffebld_constant_character1 (ffebld_conter (expr
));
1921 newlen
= ffetarget_length_character1 (val
);
1924 /* Begin FFETARGET-NULL-KLUDGE. */
1928 *length
= build_int_2 (newlen
, 0);
1929 TREE_TYPE (*length
) = ffecom_f2c_ftnlen_type_node
;
1930 high
= build_int_2 (newlen
, 0);
1931 TREE_TYPE (high
) = ffecom_f2c_ftnlen_type_node
;
1932 item
= build_string (newlen
,
1933 ffetarget_text_character1 (val
));
1934 /* End FFETARGET-NULL-KLUDGE. */
1936 = build_type_variant
1940 (ffecom_f2c_ftnlen_type_node
,
1941 ffecom_f2c_ftnlen_one_node
,
1944 TREE_CONSTANT (item
) = 1;
1945 TREE_STATIC (item
) = 1;
1946 item
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (item
)),
1950 case FFEBLD_opSYMTER
:
1952 ffesymbol s
= ffebld_symter (expr
);
1954 item
= ffesymbol_hook (s
).decl_tree
;
1955 if (item
== NULL_TREE
)
1957 s
= ffecom_sym_transform_ (s
);
1958 item
= ffesymbol_hook (s
).decl_tree
;
1960 if (ffesymbol_kind (s
) == FFEINFO_kindENTITY
)
1962 if (ffesymbol_size (s
) == FFETARGET_charactersizeNONE
)
1963 *length
= ffesymbol_hook (s
).length_tree
;
1966 *length
= build_int_2 (ffesymbol_size (s
), 0);
1967 TREE_TYPE (*length
) = ffecom_f2c_ftnlen_type_node
;
1970 else if (item
== error_mark_node
)
1971 *length
= error_mark_node
;
1973 /* FFEINFO_kindFUNCTION. */
1974 *length
= NULL_TREE
;
1975 if (!ffesymbol_hook (s
).addr
1976 && (item
!= error_mark_node
))
1977 item
= ffecom_1 (ADDR_EXPR
,
1978 build_pointer_type (TREE_TYPE (item
)),
1983 case FFEBLD_opARRAYREF
:
1985 ffecom_char_args_ (&item
, length
, ffebld_left (expr
));
1987 if (item
== error_mark_node
|| *length
== error_mark_node
)
1989 item
= *length
= error_mark_node
;
1993 item
= ffecom_arrayref_ (item
, expr
, 1);
1997 case FFEBLD_opSUBSTR
:
2001 ffebld thing
= ffebld_right (expr
);
2004 const char *char_name
;
2008 assert (ffebld_op (thing
) == FFEBLD_opITEM
);
2009 start
= ffebld_head (thing
);
2010 thing
= ffebld_trail (thing
);
2011 assert (ffebld_trail (thing
) == NULL
);
2012 end
= ffebld_head (thing
);
2014 /* Determine name for pretty-printing range-check errors. */
2015 for (left_symter
= ffebld_left (expr
);
2016 left_symter
&& ffebld_op (left_symter
) == FFEBLD_opARRAYREF
;
2017 left_symter
= ffebld_left (left_symter
))
2019 if (ffebld_op (left_symter
) == FFEBLD_opSYMTER
)
2020 char_name
= ffesymbol_text (ffebld_symter (left_symter
));
2022 char_name
= "[expr?]";
2024 ffecom_char_args_ (&item
, length
, ffebld_left (expr
));
2026 if (item
== error_mark_node
|| *length
== error_mark_node
)
2028 item
= *length
= error_mark_node
;
2032 array
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item
)));
2034 /* ~~~~Handle INTEGER*8 start/end, a la FFEBLD_opARRAYREF. */
2042 end_tree
= ffecom_expr (end
);
2043 if (flag_bounds_check
)
2044 end_tree
= ffecom_subscript_check_ (array
, end_tree
, 1, 0,
2046 end_tree
= convert (ffecom_f2c_ftnlen_type_node
,
2049 if (end_tree
== error_mark_node
)
2051 item
= *length
= error_mark_node
;
2060 start_tree
= ffecom_expr (start
);
2061 if (flag_bounds_check
)
2062 start_tree
= ffecom_subscript_check_ (array
, start_tree
, 0, 0,
2064 start_tree
= convert (ffecom_f2c_ftnlen_type_node
,
2067 if (start_tree
== error_mark_node
)
2069 item
= *length
= error_mark_node
;
2073 start_tree
= ffecom_save_tree (start_tree
);
2075 item
= ffecom_2 (PLUS_EXPR
, TREE_TYPE (item
),
2077 ffecom_2 (MINUS_EXPR
,
2078 TREE_TYPE (start_tree
),
2080 ffecom_f2c_ftnlen_one_node
));
2084 *length
= ffecom_2 (PLUS_EXPR
, ffecom_f2c_ftnlen_type_node
,
2085 ffecom_f2c_ftnlen_one_node
,
2086 ffecom_2 (MINUS_EXPR
,
2087 ffecom_f2c_ftnlen_type_node
,
2093 end_tree
= ffecom_expr (end
);
2094 if (flag_bounds_check
)
2095 end_tree
= ffecom_subscript_check_ (array
, end_tree
, 1, 0,
2097 end_tree
= convert (ffecom_f2c_ftnlen_type_node
,
2100 if (end_tree
== error_mark_node
)
2102 item
= *length
= error_mark_node
;
2106 *length
= ffecom_2 (PLUS_EXPR
, ffecom_f2c_ftnlen_type_node
,
2107 ffecom_f2c_ftnlen_one_node
,
2108 ffecom_2 (MINUS_EXPR
,
2109 ffecom_f2c_ftnlen_type_node
,
2110 end_tree
, start_tree
));
2116 case FFEBLD_opFUNCREF
:
2118 ffesymbol s
= ffebld_symter (ffebld_left (expr
));
2121 ffetargetCharacterSize size
= ffeinfo_size (ffebld_info (expr
));
2124 if (size
== FFETARGET_charactersizeNONE
)
2125 /* ~~Kludge alert! This should someday be fixed. */
2128 *length
= build_int_2 (size
, 0);
2129 TREE_TYPE (*length
) = ffecom_f2c_ftnlen_type_node
;
2131 if (ffeinfo_where (ffebld_info (ffebld_left (expr
)))
2132 == FFEINFO_whereINTRINSIC
)
2136 /* Invocation of an intrinsic returning CHARACTER*1. */
2137 item
= ffecom_expr_intrinsic_ (expr
, NULL_TREE
,
2141 ix
= ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr
)));
2142 assert (ix
!= FFECOM_gfrt
);
2143 item
= ffecom_gfrt_tree_ (ix
);
2148 item
= ffesymbol_hook (s
).decl_tree
;
2149 if (item
== NULL_TREE
)
2151 s
= ffecom_sym_transform_ (s
);
2152 item
= ffesymbol_hook (s
).decl_tree
;
2154 if (item
== error_mark_node
)
2156 item
= *length
= error_mark_node
;
2160 if (!ffesymbol_hook (s
).addr
)
2161 item
= ffecom_1_fn (item
);
2163 tempvar
= ffebld_nonter_hook (expr
);
2165 tempvar
= ffecom_1 (ADDR_EXPR
,
2166 build_pointer_type (TREE_TYPE (tempvar
)),
2169 args
= build_tree_list (NULL_TREE
, tempvar
);
2171 if (ffesymbol_where (s
) == FFEINFO_whereCONSTANT
) /* Sfunc args by value. */
2172 TREE_CHAIN (args
) = ffecom_list_expr (ffebld_right (expr
));
2175 TREE_CHAIN (args
) = build_tree_list (NULL_TREE
, *length
);
2176 if (ffesymbol_where (s
) == FFEINFO_whereINTRINSIC
)
2178 TREE_CHAIN (TREE_CHAIN (args
))
2179 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix
),
2180 ffebld_right (expr
));
2184 TREE_CHAIN (TREE_CHAIN (args
))
2185 = ffecom_list_ptr_to_expr (ffebld_right (expr
));
2189 item
= ffecom_3s (CALL_EXPR
,
2190 TREE_TYPE (TREE_TYPE (TREE_TYPE (item
))),
2191 item
, args
, NULL_TREE
);
2192 item
= ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (tempvar
), item
,
2197 case FFEBLD_opCONVERT
:
2199 ffecom_char_args_ (&item
, length
, ffebld_left (expr
));
2201 if (item
== error_mark_node
|| *length
== error_mark_node
)
2203 item
= *length
= error_mark_node
;
2207 if ((ffebld_size_known (ffebld_left (expr
))
2208 == FFETARGET_charactersizeNONE
)
2209 || (ffebld_size_known (ffebld_left (expr
)) < (ffebld_size (expr
))))
2210 { /* Possible blank-padding needed, copy into
2216 tempvar
= ffebld_nonter_hook (expr
);
2218 tempvar
= ffecom_1 (ADDR_EXPR
,
2219 build_pointer_type (TREE_TYPE (tempvar
)),
2222 newlen
= build_int_2 (ffebld_size (expr
), 0);
2223 TREE_TYPE (newlen
) = ffecom_f2c_ftnlen_type_node
;
2225 args
= build_tree_list (NULL_TREE
, tempvar
);
2226 TREE_CHAIN (args
) = build_tree_list (NULL_TREE
, item
);
2227 TREE_CHAIN (TREE_CHAIN (args
)) = build_tree_list (NULL_TREE
, newlen
);
2228 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args
)))
2229 = build_tree_list (NULL_TREE
, *length
);
2231 item
= ffecom_call_gfrt (FFECOM_gfrtCOPY
, args
, NULL_TREE
);
2232 TREE_SIDE_EFFECTS (item
) = 1;
2233 item
= ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (tempvar
), fold (item
),
2238 { /* Just truncate the length. */
2239 *length
= build_int_2 (ffebld_size (expr
), 0);
2240 TREE_TYPE (*length
) = ffecom_f2c_ftnlen_type_node
;
2245 assert ("bad op for single char arg expr" == NULL
);
2253 /* Check the size of the type to be sure it doesn't overflow the
2254 "portable" capacities of the compiler back end. `dummy' types
2255 can generally overflow the normal sizes as long as the computations
2256 themselves don't overflow. A particular target of the back end
2257 must still enforce its size requirements, though, and the back
2258 end takes care of this in stor-layout.c. */
2261 ffecom_check_size_overflow_ (ffesymbol s
, tree type
, bool dummy
)
2263 if (TREE_CODE (type
) == ERROR_MARK
)
2266 if (TYPE_SIZE (type
) == NULL_TREE
)
2269 if (TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
)
2272 /* An array is too large if size is negative or the type_size overflows
2273 or its "upper half" is larger than 3 (which would make the signed
2274 byte size and offset computations overflow). */
2276 if ((tree_int_cst_sgn (TYPE_SIZE (type
)) < 0)
2277 || (!dummy
&& (TREE_INT_CST_HIGH (TYPE_SIZE (type
)) > 3
2278 || TREE_OVERFLOW (TYPE_SIZE (type
)))))
2280 ffebad_start (FFEBAD_ARRAY_LARGE
);
2281 ffebad_string (ffesymbol_text (s
));
2282 ffebad_here (0, ffesymbol_where_line (s
), ffesymbol_where_column (s
));
2285 return error_mark_node
;
2291 /* Builds a length argument (PARM_DECL). Also wraps type in an array type
2292 where the dimension info is (1:size) where <size> is ffesymbol_size(s) if
2293 known, length_arg if not known (FFETARGET_charactersizeNONE). */
2296 ffecom_char_enhance_arg_ (tree
*xtype
, ffesymbol s
)
2298 ffetargetCharacterSize sz
= ffesymbol_size (s
);
2303 if (ffesymbol_where (s
) == FFEINFO_whereCONSTANT
)
2304 tlen
= NULL_TREE
; /* A statement function, no length passed. */
2307 if (ffesymbol_where (s
) == FFEINFO_whereDUMMY
)
2308 tlen
= ffecom_get_invented_identifier ("__g77_length_%s",
2309 ffesymbol_text (s
));
2311 tlen
= ffecom_get_invented_identifier ("__g77_%s", "length");
2312 tlen
= build_decl (PARM_DECL
, tlen
, ffecom_f2c_ftnlen_type_node
);
2313 DECL_ARTIFICIAL (tlen
) = 1;
2316 if (sz
== FFETARGET_charactersizeNONE
)
2318 assert (tlen
!= NULL_TREE
);
2319 highval
= variable_size (tlen
);
2323 highval
= build_int_2 (sz
, 0);
2324 TREE_TYPE (highval
) = ffecom_f2c_ftnlen_type_node
;
2327 type
= build_array_type (type
,
2328 build_range_type (ffecom_f2c_ftnlen_type_node
,
2329 ffecom_f2c_ftnlen_one_node
,
2336 /* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs
2338 ffecomConcatList_ catlist;
2339 ffebld expr; // expr of CHARACTER basictype.
2340 ffetargetCharacterSize max; // max chars to gather or _...NONE if no max
2341 catlist = ffecom_concat_list_gather_(catlist,expr,max);
2343 Scans expr for character subexpressions, updates and returns catlist
2346 static ffecomConcatList_
2347 ffecom_concat_list_gather_ (ffecomConcatList_ catlist
, ffebld expr
,
2348 ffetargetCharacterSize max
)
2350 ffetargetCharacterSize sz
;
2357 if ((max
!= FFETARGET_charactersizeNONE
) && (catlist
.minlen
>= max
))
2358 return catlist
; /* Don't append any more items. */
2360 switch (ffebld_op (expr
))
2362 case FFEBLD_opCONTER
:
2363 case FFEBLD_opSYMTER
:
2364 case FFEBLD_opARRAYREF
:
2365 case FFEBLD_opFUNCREF
:
2366 case FFEBLD_opSUBSTR
:
2367 case FFEBLD_opCONVERT
: /* Callers should strip this off beforehand
2368 if they don't need to preserve it. */
2369 if (catlist
.count
== catlist
.max
)
2370 { /* Make a (larger) list. */
2374 newmax
= (catlist
.max
== 0) ? 8 : catlist
.max
* 2;
2375 newx
= malloc_new_ks (malloc_pool_image (), "catlist",
2376 newmax
* sizeof (newx
[0]));
2377 if (catlist
.max
!= 0)
2379 memcpy (newx
, catlist
.exprs
, catlist
.max
* sizeof (newx
[0]));
2380 malloc_kill_ks (malloc_pool_image (), catlist
.exprs
,
2381 catlist
.max
* sizeof (newx
[0]));
2383 catlist
.max
= newmax
;
2384 catlist
.exprs
= newx
;
2386 if ((sz
= ffebld_size_known (expr
)) != FFETARGET_charactersizeNONE
)
2387 catlist
.minlen
+= sz
;
2389 ++catlist
.minlen
; /* Not true for F90; can be 0 length. */
2390 if ((sz
= ffebld_size_max (expr
)) == FFETARGET_charactersizeNONE
)
2391 catlist
.maxlen
= sz
;
2393 catlist
.maxlen
+= sz
;
2394 if ((max
!= FFETARGET_charactersizeNONE
) && (catlist
.minlen
> max
))
2395 { /* This item overlaps (or is beyond) the end
2396 of the destination. */
2397 switch (ffebld_op (expr
))
2399 case FFEBLD_opCONTER
:
2400 case FFEBLD_opSYMTER
:
2401 case FFEBLD_opARRAYREF
:
2402 case FFEBLD_opFUNCREF
:
2403 case FFEBLD_opSUBSTR
:
2404 /* ~~Do useful truncations here. */
2408 assert ("op changed or inconsistent switches!" == NULL
);
2412 catlist
.exprs
[catlist
.count
++] = expr
;
2415 case FFEBLD_opPAREN
:
2416 expr
= ffebld_left (expr
);
2417 goto recurse
; /* :::::::::::::::::::: */
2419 case FFEBLD_opCONCATENATE
:
2420 catlist
= ffecom_concat_list_gather_ (catlist
, ffebld_left (expr
), max
);
2421 expr
= ffebld_right (expr
);
2422 goto recurse
; /* :::::::::::::::::::: */
2424 #if 0 /* Breaks passing small actual arg to larger
2425 dummy arg of sfunc */
2426 case FFEBLD_opCONVERT
:
2427 expr
= ffebld_left (expr
);
2429 ffetargetCharacterSize cmax
;
2431 cmax
= catlist
.len
+ ffebld_size_known (expr
);
2433 if ((max
== FFETARGET_charactersizeNONE
) || (max
> cmax
))
2436 goto recurse
; /* :::::::::::::::::::: */
2443 assert ("bad op in _gather_" == NULL
);
2448 /* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs
2450 ffecomConcatList_ catlist;
2451 ffecom_concat_list_kill_(catlist);
2453 Anything allocated within the list info is deallocated. */
2456 ffecom_concat_list_kill_ (ffecomConcatList_ catlist
)
2458 if (catlist
.max
!= 0)
2459 malloc_kill_ks (malloc_pool_image (), catlist
.exprs
,
2460 catlist
.max
* sizeof (catlist
.exprs
[0]));
2463 /* Make list of concatenated string exprs.
2465 Returns a flattened list of concatenated subexpressions given a
2466 tree of such expressions. */
2468 static ffecomConcatList_
2469 ffecom_concat_list_new_ (ffebld expr
, ffetargetCharacterSize max
)
2471 ffecomConcatList_ catlist
;
2473 catlist
.maxlen
= catlist
.minlen
= catlist
.max
= catlist
.count
= 0;
2474 return ffecom_concat_list_gather_ (catlist
, expr
, max
);
2477 /* Provide some kind of useful info on member of aggregate area,
2478 since current g77/gcc technology does not provide debug info
2479 on these members. */
2482 ffecom_debug_kludge_ (tree aggr
, const char *aggr_type
, ffesymbol member
,
2483 tree member_type UNUSED
, ffetargetOffset offset
)
2493 for (type_id
= member_type
;
2494 TREE_CODE (type_id
) != IDENTIFIER_NODE
;
2497 switch (TREE_CODE (type_id
))
2501 type_id
= TYPE_NAME (type_id
);
2506 type_id
= TREE_TYPE (type_id
);
2510 assert ("no IDENTIFIER_NODE for type!" == NULL
);
2511 type_id
= error_mark_node
;
2517 if (ffecom_transform_only_dummies_
2518 || !ffe_is_debug_kludge ())
2519 return; /* Can't do this yet, maybe later. */
2522 + strlen (aggr_type
)
2523 + IDENTIFIER_LENGTH (DECL_NAME (aggr
));
2525 + IDENTIFIER_LENGTH (type_id
);
2528 if (((size_t) len
) >= ARRAY_SIZE (space
))
2529 buff
= malloc_new_ks (malloc_pool_image (), "debug_kludge", len
+ 1);
2533 sprintf (&buff
[0], "At (%s) `%s' plus %ld bytes",
2535 IDENTIFIER_POINTER (DECL_NAME (aggr
)),
2538 value
= build_string (len
, buff
);
2540 = build_type_variant (build_array_type (char_type_node
,
2544 build_int_2 (strlen (buff
), 0))),
2546 decl
= build_decl (VAR_DECL
,
2547 ffecom_get_identifier_ (ffesymbol_text (member
)),
2549 TREE_CONSTANT (decl
) = 1;
2550 TREE_STATIC (decl
) = 1;
2551 DECL_INITIAL (decl
) = error_mark_node
;
2552 DECL_IN_SYSTEM_HEADER (decl
) = 1; /* Don't let -Wunused complain. */
2553 decl
= start_decl (decl
, FALSE
);
2554 finish_decl (decl
, value
, FALSE
);
2556 if (buff
!= &space
[0])
2557 malloc_kill_ks (malloc_pool_image (), buff
, len
+ 1);
2560 /* ffecom_do_entry_ -- Do compilation of a particular entrypoint
2562 ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself
2563 int i; // entry# for this entrypoint (used by master fn)
2564 ffecom_do_entrypoint_(s,i);
2566 Makes a public entry point that calls our private master fn (already
2570 ffecom_do_entry_ (ffesymbol fn
, int entrynum
)
2573 tree type
; /* Type of function. */
2574 tree multi_retval
; /* Var holding return value (union). */
2575 tree result
; /* Var holding result. */
2576 ffeinfoBasictype bt
;
2580 bool charfunc
; /* All entry points return same type
2582 bool cmplxfunc
; /* Use f2c way of returning COMPLEX. */
2583 bool multi
; /* Master fn has multiple return types. */
2584 bool altreturning
= FALSE
; /* This entry point has alternate
2586 location_t old_loc
= input_location
;
2588 input_filename
= ffesymbol_where_filename (fn
);
2589 input_line
= ffesymbol_where_filelinenum (fn
);
2591 ffecom_doing_entry_
= TRUE
; /* Don't bother with array dimensions. */
2593 switch (ffecom_primary_entry_kind_
)
2595 case FFEINFO_kindFUNCTION
:
2597 /* Determine actual return type for function. */
2599 gt
= FFEGLOBAL_typeFUNC
;
2600 bt
= ffesymbol_basictype (fn
);
2601 kt
= ffesymbol_kindtype (fn
);
2602 if (bt
== FFEINFO_basictypeNONE
)
2604 ffeimplic_establish_symbol (fn
);
2605 if (ffesymbol_funcresult (fn
) != NULL
)
2606 ffeimplic_establish_symbol (ffesymbol_funcresult (fn
));
2607 bt
= ffesymbol_basictype (fn
);
2608 kt
= ffesymbol_kindtype (fn
);
2611 if (bt
== FFEINFO_basictypeCHARACTER
)
2612 charfunc
= TRUE
, cmplxfunc
= FALSE
;
2613 else if ((bt
== FFEINFO_basictypeCOMPLEX
)
2614 && ffesymbol_is_f2c (fn
))
2615 charfunc
= FALSE
, cmplxfunc
= TRUE
;
2617 charfunc
= cmplxfunc
= FALSE
;
2620 type
= ffecom_tree_fun_type_void
;
2621 else if (ffesymbol_is_f2c (fn
))
2622 type
= ffecom_tree_fun_type
[bt
][kt
];
2624 type
= build_function_type (ffecom_tree_type
[bt
][kt
], NULL_TREE
);
2626 if ((type
== NULL_TREE
)
2627 || (TREE_TYPE (type
) == NULL_TREE
))
2628 type
= ffecom_tree_fun_type_void
; /* _sym_exec_transition. */
2630 multi
= (ffecom_master_bt_
== FFEINFO_basictypeNONE
);
2633 case FFEINFO_kindSUBROUTINE
:
2634 gt
= FFEGLOBAL_typeSUBR
;
2635 bt
= FFEINFO_basictypeNONE
;
2636 kt
= FFEINFO_kindtypeNONE
;
2637 if (ffecom_is_altreturning_
)
2638 { /* Am _I_ altreturning? */
2639 for (item
= ffesymbol_dummyargs (fn
);
2641 item
= ffebld_trail (item
))
2643 if (ffebld_op (ffebld_head (item
)) == FFEBLD_opSTAR
)
2645 altreturning
= TRUE
;
2650 type
= ffecom_tree_subr_type
;
2652 type
= ffecom_tree_fun_type_void
;
2655 type
= ffecom_tree_fun_type_void
;
2662 assert ("say what??" == NULL
);
2664 case FFEINFO_kindANY
:
2665 gt
= FFEGLOBAL_typeANY
;
2666 bt
= FFEINFO_basictypeNONE
;
2667 kt
= FFEINFO_kindtypeNONE
;
2668 type
= error_mark_node
;
2675 /* build_decl uses the current lineno and input_filename to set the decl
2676 source info. So, I've putzed with ffestd and ffeste code to update that
2677 source info to point to the appropriate statement just before calling
2678 ffecom_do_entrypoint (which calls this fn). */
2680 start_function (ffecom_get_external_identifier_ (fn
),
2682 0, /* nested/inline */
2683 1); /* TREE_PUBLIC */
2685 if (((g
= ffesymbol_global (fn
)) != NULL
)
2686 && ((ffeglobal_type (g
) == gt
)
2687 || (ffeglobal_type (g
) == FFEGLOBAL_typeEXT
)))
2689 ffeglobal_set_hook (g
, current_function_decl
);
2692 /* Reset args in master arg list so they get retransitioned. */
2694 for (item
= ffecom_master_arglist_
;
2696 item
= ffebld_trail (item
))
2701 arg
= ffebld_head (item
);
2702 if (ffebld_op (arg
) != FFEBLD_opSYMTER
)
2703 continue; /* Alternate return or some such thing. */
2704 s
= ffebld_symter (arg
);
2705 ffesymbol_hook (s
).decl_tree
= NULL_TREE
;
2706 ffesymbol_hook (s
).length_tree
= NULL_TREE
;
2709 /* Build dummy arg list for this entry point. */
2711 if (charfunc
|| cmplxfunc
)
2712 { /* Prepend arg for where result goes. */
2717 type
= ffecom_tree_type
[FFEINFO_basictypeCHARACTER
][kt
];
2719 type
= ffecom_tree_type
[FFEINFO_basictypeCOMPLEX
][kt
];
2721 result
= ffecom_get_invented_identifier ("__g77_%s", "result");
2723 /* Make length arg _and_ enhance type info for CHAR arg itself. */
2726 length
= ffecom_char_enhance_arg_ (&type
, fn
);
2728 length
= NULL_TREE
; /* Not ref'd if !charfunc. */
2730 type
= build_pointer_type (type
);
2731 result
= build_decl (PARM_DECL
, result
, type
);
2733 push_parm_decl (result
);
2734 ffecom_func_result_
= result
;
2738 push_parm_decl (length
);
2739 ffecom_func_length_
= length
;
2743 result
= DECL_RESULT (current_function_decl
);
2745 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn
), FALSE
);
2747 store_parm_decls (0);
2749 ffecom_start_compstmt ();
2750 /* Disallow temp vars at this level. */
2751 current_binding_level
->prep_state
= 2;
2753 /* Make local var to hold return type for multi-type master fn. */
2757 multi_retval
= ffecom_get_invented_identifier ("__g77_%s",
2759 multi_retval
= build_decl (VAR_DECL
, multi_retval
,
2760 ffecom_multi_type_node_
);
2761 multi_retval
= start_decl (multi_retval
, FALSE
);
2762 finish_decl (multi_retval
, NULL_TREE
, FALSE
);
2765 multi_retval
= NULL_TREE
; /* Not actually ref'd if !multi. */
2767 /* Here we emit the actual code for the entry point. */
2773 tree arglist
= NULL_TREE
;
2774 tree
*plist
= &arglist
;
2780 /* Prepare actual arg list based on master arg list. */
2782 for (list
= ffecom_master_arglist_
;
2784 list
= ffebld_trail (list
))
2786 arg
= ffebld_head (list
);
2787 if (ffebld_op (arg
) != FFEBLD_opSYMTER
)
2789 s
= ffebld_symter (arg
);
2790 if (ffesymbol_hook (s
).decl_tree
== NULL_TREE
2791 || ffesymbol_hook (s
).decl_tree
== error_mark_node
)
2792 actarg
= null_pointer_node
; /* We don't have this arg. */
2794 actarg
= ffesymbol_hook (s
).decl_tree
;
2795 *plist
= build_tree_list (NULL_TREE
, actarg
);
2796 plist
= &TREE_CHAIN (*plist
);
2799 /* This code appends the length arguments for character
2800 variables/arrays. */
2802 for (list
= ffecom_master_arglist_
;
2804 list
= ffebld_trail (list
))
2806 arg
= ffebld_head (list
);
2807 if (ffebld_op (arg
) != FFEBLD_opSYMTER
)
2809 s
= ffebld_symter (arg
);
2810 if (ffesymbol_basictype (s
) != FFEINFO_basictypeCHARACTER
)
2811 continue; /* Only looking for CHARACTER arguments. */
2812 if (ffesymbol_kind (s
) != FFEINFO_kindENTITY
)
2813 continue; /* Only looking for variables and arrays. */
2814 if (ffesymbol_hook (s
).length_tree
== NULL_TREE
2815 || ffesymbol_hook (s
).length_tree
== error_mark_node
)
2816 actarg
= ffecom_f2c_ftnlen_zero_node
; /* We don't have this arg. */
2818 actarg
= ffesymbol_hook (s
).length_tree
;
2819 *plist
= build_tree_list (NULL_TREE
, actarg
);
2820 plist
= &TREE_CHAIN (*plist
);
2823 /* Prepend character-value return info to actual arg list. */
2827 prepend
= build_tree_list (NULL_TREE
, ffecom_func_result_
);
2828 TREE_CHAIN (prepend
)
2829 = build_tree_list (NULL_TREE
, ffecom_func_length_
);
2830 TREE_CHAIN (TREE_CHAIN (prepend
)) = arglist
;
2834 /* Prepend multi-type return value to actual arg list. */
2839 = build_tree_list (NULL_TREE
,
2840 ffecom_1 (ADDR_EXPR
,
2841 build_pointer_type (TREE_TYPE (multi_retval
)),
2843 TREE_CHAIN (prepend
) = arglist
;
2847 /* Prepend my entry-point number to the actual arg list. */
2849 prepend
= build_tree_list (NULL_TREE
, build_int_2 (entrynum
, 0));
2850 TREE_CHAIN (prepend
) = arglist
;
2853 /* Build the call to the master function. */
2855 master_fn
= ffecom_1_fn (ffecom_previous_function_decl_
);
2856 call
= ffecom_3s (CALL_EXPR
,
2857 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn
))),
2858 master_fn
, arglist
, NULL_TREE
);
2860 /* Decide whether the master function is a function or subroutine, and
2861 handle the return value for my entry point. */
2863 if (charfunc
|| ((ffecom_primary_entry_kind_
== FFEINFO_kindSUBROUTINE
)
2866 expand_expr_stmt (call
);
2867 expand_null_return ();
2869 else if (multi
&& cmplxfunc
)
2871 expand_expr_stmt (call
);
2873 = ffecom_1 (INDIRECT_REF
,
2874 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result
))),
2876 result
= ffecom_modify (NULL_TREE
, result
,
2877 ffecom_2 (COMPONENT_REF
, TREE_TYPE (result
),
2879 ffecom_multi_fields_
[bt
][kt
]));
2880 expand_expr_stmt (result
);
2881 expand_null_return ();
2885 expand_expr_stmt (call
);
2887 = ffecom_modify (NULL_TREE
, result
,
2888 convert (TREE_TYPE (result
),
2889 ffecom_2 (COMPONENT_REF
,
2890 ffecom_tree_type
[bt
][kt
],
2892 ffecom_multi_fields_
[bt
][kt
])));
2893 expand_return (result
);
2898 = ffecom_1 (INDIRECT_REF
,
2899 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result
))),
2901 result
= ffecom_modify (NULL_TREE
, result
, call
);
2902 expand_expr_stmt (result
);
2903 expand_null_return ();
2907 result
= ffecom_modify (NULL_TREE
,
2909 convert (TREE_TYPE (result
),
2911 expand_return (result
);
2915 ffecom_end_compstmt ();
2917 finish_function (0);
2919 input_location
= old_loc
;
2921 ffecom_doing_entry_
= FALSE
;
2924 /* Transform expr into gcc tree with possible destination
2926 Recursive descent on expr while making corresponding tree nodes and
2927 attaching type info and such. If destination supplied and compatible
2928 with temporary that would be made in certain cases, temporary isn't
2929 made, destination used instead, and dest_used flag set TRUE. */
2932 ffecom_expr_ (ffebld expr
, tree dest_tree
, ffebld dest
,
2933 bool *dest_used
, bool assignp
, bool widenp
)
2938 ffeinfoBasictype bt
;
2941 tree dt
; /* decl_tree for an ffesymbol. */
2942 tree tree_type
, tree_type_x
;
2945 enum tree_code code
;
2947 assert (expr
!= NULL
);
2949 if (dest_used
!= NULL
)
2952 bt
= ffeinfo_basictype (ffebld_info (expr
));
2953 kt
= ffeinfo_kindtype (ffebld_info (expr
));
2954 tree_type
= ffecom_tree_type
[bt
][kt
];
2956 /* Widen integral arithmetic as desired while preserving signedness. */
2957 tree_type_x
= NULL_TREE
;
2958 if (widenp
&& tree_type
2959 && GET_MODE_CLASS (TYPE_MODE (tree_type
)) == MODE_INT
2960 && TYPE_PRECISION (tree_type
) < TYPE_PRECISION (sizetype
))
2961 tree_type_x
= (TREE_UNSIGNED (tree_type
) ? usizetype
: ssizetype
);
2963 switch (ffebld_op (expr
))
2965 case FFEBLD_opACCTER
:
2968 ffebit bits
= ffebld_accter_bits (expr
);
2969 ffetargetOffset source_offset
= 0;
2970 ffetargetOffset dest_offset
= ffebld_accter_pad (expr
);
2973 assert (dest_offset
== 0
2974 || (bt
== FFEINFO_basictypeCHARACTER
2975 && kt
== FFEINFO_kindtypeCHARACTER1
));
2980 ffebldConstantUnion cu
;
2983 ffebldConstantArray ca
= ffebld_accter (expr
);
2985 ffebit_test (bits
, source_offset
, &value
, &length
);
2991 for (i
= 0; i
< length
; ++i
)
2993 cu
= ffebld_constantarray_get (ca
, bt
, kt
,
2996 t
= ffecom_constantunion (&cu
, bt
, kt
, tree_type
);
2999 && dest_offset
!= 0)
3000 purpose
= build_int_2 (dest_offset
, 0);
3002 purpose
= NULL_TREE
;
3004 if (list
== NULL_TREE
)
3005 list
= item
= build_tree_list (purpose
, t
);
3008 TREE_CHAIN (item
) = build_tree_list (purpose
, t
);
3009 item
= TREE_CHAIN (item
);
3013 source_offset
+= length
;
3014 dest_offset
+= length
;
3018 item
= build_int_2 ((ffebld_accter_size (expr
)
3019 + ffebld_accter_pad (expr
)) - 1, 0);
3020 ffebit_kill (ffebld_accter_bits (expr
));
3021 TREE_TYPE (item
) = ffecom_integer_type_node
;
3025 build_range_type (ffecom_integer_type_node
,
3026 ffecom_integer_zero_node
,
3028 list
= build_constructor (item
, list
);
3029 TREE_CONSTANT (list
) = 1;
3030 TREE_STATIC (list
) = 1;
3033 case FFEBLD_opARRTER
:
3038 if (ffebld_arrter_pad (expr
) == 0)
3042 assert (bt
== FFEINFO_basictypeCHARACTER
3043 && kt
== FFEINFO_kindtypeCHARACTER1
);
3045 /* Becomes PURPOSE first time through loop. */
3046 item
= build_int_2 (ffebld_arrter_pad (expr
), 0);
3049 for (i
= 0; i
< ffebld_arrter_size (expr
); ++i
)
3051 ffebldConstantUnion cu
3052 = ffebld_constantarray_get (ffebld_arrter (expr
), bt
, kt
, i
);
3054 t
= ffecom_constantunion (&cu
, bt
, kt
, tree_type
);
3056 if (list
== NULL_TREE
)
3057 /* Assume item is PURPOSE first time through loop. */
3058 list
= item
= build_tree_list (item
, t
);
3061 TREE_CHAIN (item
) = build_tree_list (NULL_TREE
, t
);
3062 item
= TREE_CHAIN (item
);
3067 item
= build_int_2 ((ffebld_arrter_size (expr
)
3068 + ffebld_arrter_pad (expr
)) - 1, 0);
3069 TREE_TYPE (item
) = ffecom_integer_type_node
;
3073 build_range_type (ffecom_integer_type_node
,
3074 ffecom_integer_zero_node
,
3076 list
= build_constructor (item
, list
);
3077 TREE_CONSTANT (list
) = 1;
3078 TREE_STATIC (list
) = 1;
3081 case FFEBLD_opCONTER
:
3082 assert (ffebld_conter_pad (expr
) == 0);
3084 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr
)),
3088 case FFEBLD_opSYMTER
:
3089 if ((ffebld_symter_generic (expr
) != FFEINTRIN_genNONE
)
3090 || (ffebld_symter_specific (expr
) != FFEINTRIN_specNONE
))
3091 return ffecom_ptr_to_expr (expr
); /* Same as %REF(intrinsic). */
3092 s
= ffebld_symter (expr
);
3093 t
= ffesymbol_hook (s
).decl_tree
;
3096 { /* ASSIGN'ed-label expr. */
3097 if (ffe_is_ugly_assign ())
3099 /* User explicitly wants ASSIGN'ed variables to be at the same
3100 memory address as the variables when used in non-ASSIGN
3101 contexts. That can make old, arcane, non-standard code
3102 work, but don't try to do it when a pointer wouldn't fit
3103 in the normal variable (take other approach, and warn,
3108 s
= ffecom_sym_transform_ (s
);
3109 t
= ffesymbol_hook (s
).decl_tree
;
3110 assert (t
!= NULL_TREE
);
3113 if (t
== error_mark_node
)
3116 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t
)))
3117 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node
))))
3119 if (ffesymbol_hook (s
).addr
)
3120 t
= ffecom_1 (INDIRECT_REF
,
3121 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t
))), t
);
3125 if (ffesymbol_hook (s
).assign_tree
== NULL_TREE
)
3127 /* xgettext:no-c-format */
3128 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
3129 FFEBAD_severityWARNING
);
3130 ffebad_string (ffesymbol_text (s
));
3131 ffebad_here (0, ffesymbol_where_line (s
),
3132 ffesymbol_where_column (s
));
3137 /* Don't use the normal variable's tree for ASSIGN, though mark
3138 it as in the system header (housekeeping). Use an explicit,
3139 specially created sibling that is known to be wide enough
3140 to hold pointers to labels. */
3143 && TREE_CODE (t
) == VAR_DECL
)
3144 DECL_IN_SYSTEM_HEADER (t
) = 1; /* Don't let -Wunused complain. */
3146 t
= ffesymbol_hook (s
).assign_tree
;
3149 s
= ffecom_sym_transform_assign_ (s
);
3150 t
= ffesymbol_hook (s
).assign_tree
;
3151 assert (t
!= NULL_TREE
);
3158 s
= ffecom_sym_transform_ (s
);
3159 t
= ffesymbol_hook (s
).decl_tree
;
3160 assert (t
!= NULL_TREE
);
3162 if (ffesymbol_hook (s
).addr
)
3163 t
= ffecom_1 (INDIRECT_REF
,
3164 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t
))), t
);
3168 case FFEBLD_opARRAYREF
:
3169 return ffecom_arrayref_ (NULL_TREE
, expr
, 0);
3171 case FFEBLD_opUPLUS
:
3172 left
= ffecom_expr_ (ffebld_left (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3173 return ffecom_1 (NOP_EXPR
, tree_type
, left
);
3175 case FFEBLD_opPAREN
:
3176 /* ~~~Make sure Fortran rules respected here */
3177 left
= ffecom_expr_ (ffebld_left (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3178 return ffecom_1 (NOP_EXPR
, tree_type
, left
);
3180 case FFEBLD_opUMINUS
:
3181 left
= ffecom_expr_ (ffebld_left (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3184 tree_type
= tree_type_x
;
3185 left
= convert (tree_type
, left
);
3187 return ffecom_1 (NEGATE_EXPR
, tree_type
, left
);
3190 left
= ffecom_expr_ (ffebld_left (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3191 right
= ffecom_expr_ (ffebld_right (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3194 tree_type
= tree_type_x
;
3195 left
= convert (tree_type
, left
);
3196 right
= convert (tree_type
, right
);
3198 return ffecom_2 (PLUS_EXPR
, tree_type
, left
, right
);
3200 case FFEBLD_opSUBTRACT
:
3201 left
= ffecom_expr_ (ffebld_left (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3202 right
= ffecom_expr_ (ffebld_right (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3205 tree_type
= tree_type_x
;
3206 left
= convert (tree_type
, left
);
3207 right
= convert (tree_type
, right
);
3209 return ffecom_2 (MINUS_EXPR
, tree_type
, left
, right
);
3211 case FFEBLD_opMULTIPLY
:
3212 left
= ffecom_expr_ (ffebld_left (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3213 right
= ffecom_expr_ (ffebld_right (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3216 tree_type
= tree_type_x
;
3217 left
= convert (tree_type
, left
);
3218 right
= convert (tree_type
, right
);
3220 return ffecom_2 (MULT_EXPR
, tree_type
, left
, right
);
3222 case FFEBLD_opDIVIDE
:
3223 left
= ffecom_expr_ (ffebld_left (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3224 right
= ffecom_expr_ (ffebld_right (expr
), NULL
, NULL
, NULL
, FALSE
, widenp
);
3227 tree_type
= tree_type_x
;
3228 left
= convert (tree_type
, left
);
3229 right
= convert (tree_type
, right
);
3231 return ffecom_tree_divide_ (tree_type
, left
, right
,
3232 dest_tree
, dest
, dest_used
,
3233 ffebld_nonter_hook (expr
));
3235 case FFEBLD_opPOWER
:
3237 ffebld left
= ffebld_left (expr
);
3238 ffebld right
= ffebld_right (expr
);
3240 ffeinfoKindtype rtkt
;
3241 ffeinfoKindtype ltkt
;
3244 switch (ffeinfo_basictype (ffebld_info (right
)))
3247 case FFEINFO_basictypeINTEGER
:
3250 item
= ffecom_expr_power_integer_ (expr
);
3251 if (item
!= NULL_TREE
)
3255 rtkt
= FFEINFO_kindtypeINTEGER1
;
3256 switch (ffeinfo_basictype (ffebld_info (left
)))
3258 case FFEINFO_basictypeINTEGER
:
3259 if ((ffeinfo_kindtype (ffebld_info (left
))
3260 == FFEINFO_kindtypeINTEGER4
)
3261 || (ffeinfo_kindtype (ffebld_info (right
))
3262 == FFEINFO_kindtypeINTEGER4
))
3264 code
= FFECOM_gfrtPOW_QQ
;
3265 ltkt
= FFEINFO_kindtypeINTEGER4
;
3266 rtkt
= FFEINFO_kindtypeINTEGER4
;
3270 code
= FFECOM_gfrtPOW_II
;
3271 ltkt
= FFEINFO_kindtypeINTEGER1
;
3275 case FFEINFO_basictypeREAL
:
3276 if (ffeinfo_kindtype (ffebld_info (left
))
3277 == FFEINFO_kindtypeREAL1
)
3279 code
= FFECOM_gfrtPOW_RI
;
3280 ltkt
= FFEINFO_kindtypeREAL1
;
3284 code
= FFECOM_gfrtPOW_DI
;
3285 ltkt
= FFEINFO_kindtypeREAL2
;
3289 case FFEINFO_basictypeCOMPLEX
:
3290 if (ffeinfo_kindtype (ffebld_info (left
))
3291 == FFEINFO_kindtypeREAL1
)
3293 code
= FFECOM_gfrtPOW_CI
; /* Overlapping result okay. */
3294 ltkt
= FFEINFO_kindtypeREAL1
;
3298 code
= FFECOM_gfrtPOW_ZI
; /* Overlapping result okay. */
3299 ltkt
= FFEINFO_kindtypeREAL2
;
3304 assert ("bad pow_*i" == NULL
);
3305 code
= FFECOM_gfrtPOW_CI
; /* Overlapping result okay. */
3306 ltkt
= FFEINFO_kindtypeREAL1
;
3309 if (ffeinfo_kindtype (ffebld_info (left
)) != ltkt
)
3310 left
= ffeexpr_convert (left
, NULL
, NULL
,
3311 ffeinfo_basictype (ffebld_info (left
)),
3313 FFETARGET_charactersizeNONE
,
3314 FFEEXPR_contextLET
);
3315 if (ffeinfo_kindtype (ffebld_info (right
)) != rtkt
)
3316 right
= ffeexpr_convert (right
, NULL
, NULL
,
3317 FFEINFO_basictypeINTEGER
,
3319 FFETARGET_charactersizeNONE
,
3320 FFEEXPR_contextLET
);
3323 case FFEINFO_basictypeREAL
:
3324 if (ffeinfo_kindtype (ffebld_info (left
)) == FFEINFO_kindtypeREAL1
)
3325 left
= ffeexpr_convert (left
, NULL
, NULL
, FFEINFO_basictypeREAL
,
3326 FFEINFO_kindtypeREALDOUBLE
, 0,
3327 FFETARGET_charactersizeNONE
,
3328 FFEEXPR_contextLET
);
3329 if (ffeinfo_kindtype (ffebld_info (right
))
3330 == FFEINFO_kindtypeREAL1
)
3331 right
= ffeexpr_convert (right
, NULL
, NULL
,
3332 FFEINFO_basictypeREAL
,
3333 FFEINFO_kindtypeREALDOUBLE
, 0,
3334 FFETARGET_charactersizeNONE
,
3335 FFEEXPR_contextLET
);
3336 /* We used to call FFECOM_gfrtPOW_DD here,
3337 which passes arguments by reference. */
3338 code
= FFECOM_gfrtL_POW
;
3339 /* Pass arguments by value. */
3343 case FFEINFO_basictypeCOMPLEX
:
3344 if (ffeinfo_kindtype (ffebld_info (left
)) == FFEINFO_kindtypeREAL1
)
3345 left
= ffeexpr_convert (left
, NULL
, NULL
,
3346 FFEINFO_basictypeCOMPLEX
,
3347 FFEINFO_kindtypeREALDOUBLE
, 0,
3348 FFETARGET_charactersizeNONE
,
3349 FFEEXPR_contextLET
);
3350 if (ffeinfo_kindtype (ffebld_info (right
))
3351 == FFEINFO_kindtypeREAL1
)
3352 right
= ffeexpr_convert (right
, NULL
, NULL
,
3353 FFEINFO_basictypeCOMPLEX
,
3354 FFEINFO_kindtypeREALDOUBLE
, 0,
3355 FFETARGET_charactersizeNONE
,
3356 FFEEXPR_contextLET
);
3357 code
= FFECOM_gfrtPOW_ZZ
; /* Overlapping result okay. */
3358 ref
= TRUE
; /* Pass arguments by reference. */
3362 assert ("bad pow_x*" == NULL
);
3363 code
= FFECOM_gfrtPOW_II
;
3366 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code
),
3367 ffecom_gfrt_kindtype (code
),
3368 (ffe_is_f2c_library ()
3369 && ffecom_gfrt_complex_
[code
]),
3370 tree_type
, left
, right
,
3371 dest_tree
, dest
, dest_used
,
3372 NULL_TREE
, FALSE
, ref
,
3373 ffebld_nonter_hook (expr
));
3379 case FFEINFO_basictypeLOGICAL
:
3380 item
= ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr
)));
3381 return convert (tree_type
, item
);
3383 case FFEINFO_basictypeINTEGER
:
3384 return ffecom_1 (BIT_NOT_EXPR
, tree_type
,
3385 ffecom_expr (ffebld_left (expr
)));
3388 assert ("NOT bad basictype" == NULL
);
3390 case FFEINFO_basictypeANY
:
3391 return error_mark_node
;
3395 case FFEBLD_opFUNCREF
:
3396 assert (ffeinfo_basictype (ffebld_info (expr
))
3397 != FFEINFO_basictypeCHARACTER
);
3399 case FFEBLD_opSUBRREF
:
3400 if (ffeinfo_where (ffebld_info (ffebld_left (expr
)))
3401 == FFEINFO_whereINTRINSIC
)
3402 { /* Invocation of an intrinsic. */
3403 item
= ffecom_expr_intrinsic_ (expr
, dest_tree
, dest
,
3407 s
= ffebld_symter (ffebld_left (expr
));
3408 dt
= ffesymbol_hook (s
).decl_tree
;
3409 if (dt
== NULL_TREE
)
3411 s
= ffecom_sym_transform_ (s
);
3412 dt
= ffesymbol_hook (s
).decl_tree
;
3414 if (dt
== error_mark_node
)
3417 if (ffesymbol_hook (s
).addr
)
3420 item
= ffecom_1_fn (dt
);
3422 if (ffesymbol_where (s
) == FFEINFO_whereCONSTANT
)
3423 args
= ffecom_list_expr (ffebld_right (expr
));
3425 args
= ffecom_list_ptr_to_expr (ffebld_right (expr
));
3427 if (args
== error_mark_node
)
3428 return error_mark_node
;
3430 item
= ffecom_call_ (item
, kt
,
3431 ffesymbol_is_f2c (s
)
3432 && (bt
== FFEINFO_basictypeCOMPLEX
)
3433 && (ffesymbol_where (s
)
3434 != FFEINFO_whereCONSTANT
),
3437 dest_tree
, dest
, dest_used
,
3438 error_mark_node
, FALSE
,
3439 ffebld_nonter_hook (expr
));
3440 TREE_SIDE_EFFECTS (item
) = 1;
3446 case FFEINFO_basictypeLOGICAL
:
3448 = ffecom_2 (TRUTH_ANDIF_EXPR
, integer_type_node
,
3449 ffecom_truth_value (ffecom_expr (ffebld_left (expr
))),
3450 ffecom_truth_value (ffecom_expr (ffebld_right (expr
))));
3451 return convert (tree_type
, item
);
3453 case FFEINFO_basictypeINTEGER
:
3454 return ffecom_2 (BIT_AND_EXPR
, tree_type
,
3455 ffecom_expr (ffebld_left (expr
)),
3456 ffecom_expr (ffebld_right (expr
)));
3459 assert ("AND bad basictype" == NULL
);
3461 case FFEINFO_basictypeANY
:
3462 return error_mark_node
;
3469 case FFEINFO_basictypeLOGICAL
:
3471 = ffecom_2 (TRUTH_ORIF_EXPR
, integer_type_node
,
3472 ffecom_truth_value (ffecom_expr (ffebld_left (expr
))),
3473 ffecom_truth_value (ffecom_expr (ffebld_right (expr
))));
3474 return convert (tree_type
, item
);
3476 case FFEINFO_basictypeINTEGER
:
3477 return ffecom_2 (BIT_IOR_EXPR
, tree_type
,
3478 ffecom_expr (ffebld_left (expr
)),
3479 ffecom_expr (ffebld_right (expr
)));
3482 assert ("OR bad basictype" == NULL
);
3484 case FFEINFO_basictypeANY
:
3485 return error_mark_node
;
3493 case FFEINFO_basictypeLOGICAL
:
3495 = ffecom_2 (NE_EXPR
, integer_type_node
,
3496 ffecom_expr (ffebld_left (expr
)),
3497 ffecom_expr (ffebld_right (expr
)));
3498 return convert (tree_type
, ffecom_truth_value (item
));
3500 case FFEINFO_basictypeINTEGER
:
3501 return ffecom_2 (BIT_XOR_EXPR
, tree_type
,
3502 ffecom_expr (ffebld_left (expr
)),
3503 ffecom_expr (ffebld_right (expr
)));
3506 assert ("XOR/NEQV bad basictype" == NULL
);
3508 case FFEINFO_basictypeANY
:
3509 return error_mark_node
;
3516 case FFEINFO_basictypeLOGICAL
:
3518 = ffecom_2 (EQ_EXPR
, integer_type_node
,
3519 ffecom_expr (ffebld_left (expr
)),
3520 ffecom_expr (ffebld_right (expr
)));
3521 return convert (tree_type
, ffecom_truth_value (item
));
3523 case FFEINFO_basictypeINTEGER
:
3525 ffecom_1 (BIT_NOT_EXPR
, tree_type
,
3526 ffecom_2 (BIT_XOR_EXPR
, tree_type
,
3527 ffecom_expr (ffebld_left (expr
)),
3528 ffecom_expr (ffebld_right (expr
))));
3531 assert ("EQV bad basictype" == NULL
);
3533 case FFEINFO_basictypeANY
:
3534 return error_mark_node
;
3538 case FFEBLD_opCONVERT
:
3539 if (ffebld_op (ffebld_left (expr
)) == FFEBLD_opANY
)
3540 return error_mark_node
;
3544 case FFEINFO_basictypeLOGICAL
:
3545 case FFEINFO_basictypeINTEGER
:
3546 case FFEINFO_basictypeREAL
:
3547 return convert (tree_type
, ffecom_expr (ffebld_left (expr
)));
3549 case FFEINFO_basictypeCOMPLEX
:
3550 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr
))))
3552 case FFEINFO_basictypeINTEGER
:
3553 case FFEINFO_basictypeLOGICAL
:
3554 case FFEINFO_basictypeREAL
:
3555 item
= ffecom_expr (ffebld_left (expr
));
3556 if (item
== error_mark_node
)
3557 return error_mark_node
;
3558 /* convert() takes care of converting to the subtype first,
3559 at least in gcc-2.7.2. */
3560 item
= convert (tree_type
, item
);
3563 case FFEINFO_basictypeCOMPLEX
:
3564 return convert (tree_type
, ffecom_expr (ffebld_left (expr
)));
3567 assert ("CONVERT COMPLEX bad basictype" == NULL
);
3569 case FFEINFO_basictypeANY
:
3570 return error_mark_node
;
3575 assert ("CONVERT bad basictype" == NULL
);
3577 case FFEINFO_basictypeANY
:
3578 return error_mark_node
;
3584 goto relational
; /* :::::::::::::::::::: */
3588 goto relational
; /* :::::::::::::::::::: */
3592 goto relational
; /* :::::::::::::::::::: */
3596 goto relational
; /* :::::::::::::::::::: */
3600 goto relational
; /* :::::::::::::::::::: */
3605 relational
: /* :::::::::::::::::::: */
3606 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr
))))
3608 case FFEINFO_basictypeLOGICAL
:
3609 case FFEINFO_basictypeINTEGER
:
3610 case FFEINFO_basictypeREAL
:
3611 item
= ffecom_2 (code
, integer_type_node
,
3612 ffecom_expr (ffebld_left (expr
)),
3613 ffecom_expr (ffebld_right (expr
)));
3614 return convert (tree_type
, item
);
3616 case FFEINFO_basictypeCOMPLEX
:
3617 assert (code
== EQ_EXPR
|| code
== NE_EXPR
);
3620 tree arg1
= ffecom_expr (ffebld_left (expr
));
3621 tree arg2
= ffecom_expr (ffebld_right (expr
));
3623 if (arg1
== error_mark_node
|| arg2
== error_mark_node
)
3624 return error_mark_node
;
3626 arg1
= ffecom_save_tree (arg1
);
3627 arg2
= ffecom_save_tree (arg2
);
3629 if (TREE_CODE (TREE_TYPE (arg1
)) == COMPLEX_TYPE
)
3631 real_type
= TREE_TYPE (TREE_TYPE (arg1
));
3632 assert (real_type
== TREE_TYPE (TREE_TYPE (arg2
)));
3636 real_type
= TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1
)));
3637 assert (real_type
== TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2
))));
3641 = ffecom_2 (TRUTH_ANDIF_EXPR
, integer_type_node
,
3642 ffecom_2 (EQ_EXPR
, integer_type_node
,
3643 ffecom_1 (REALPART_EXPR
, real_type
, arg1
),
3644 ffecom_1 (REALPART_EXPR
, real_type
, arg2
)),
3645 ffecom_2 (EQ_EXPR
, integer_type_node
,
3646 ffecom_1 (IMAGPART_EXPR
, real_type
, arg1
),
3647 ffecom_1 (IMAGPART_EXPR
, real_type
,
3649 if (code
== EQ_EXPR
)
3650 item
= ffecom_truth_value (item
);
3652 item
= ffecom_truth_value_invert (item
);
3653 return convert (tree_type
, item
);
3656 case FFEINFO_basictypeCHARACTER
:
3658 ffebld left
= ffebld_left (expr
);
3659 ffebld right
= ffebld_right (expr
);
3665 /* f2c run-time functions do the implicit blank-padding for us,
3666 so we don't usually have to implement blank-padding ourselves.
3667 (The exception is when we pass an argument to a separately
3668 compiled statement function -- if we know the arg is not the
3669 same length as the dummy, we must truncate or extend it. If
3670 we "inline" statement functions, that necessity goes away as
3673 Strip off the CONVERT operators that blank-pad. (Truncation by
3674 CONVERT shouldn't happen here, but it can happen in
3677 while (ffebld_op (left
) == FFEBLD_opCONVERT
)
3678 left
= ffebld_left (left
);
3679 while (ffebld_op (right
) == FFEBLD_opCONVERT
)
3680 right
= ffebld_left (right
);
3682 left_tree
= ffecom_arg_ptr_to_expr (left
, &left_length
);
3683 right_tree
= ffecom_arg_ptr_to_expr (right
, &right_length
);
3685 if (left_tree
== error_mark_node
|| left_length
== error_mark_node
3686 || right_tree
== error_mark_node
3687 || right_length
== error_mark_node
)
3688 return error_mark_node
;
3690 if ((ffebld_size_known (left
) == 1)
3691 && (ffebld_size_known (right
) == 1))
3694 = ffecom_1 (INDIRECT_REF
,
3695 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree
))),
3698 = ffecom_1 (INDIRECT_REF
,
3699 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree
))),
3703 = ffecom_2 (code
, integer_type_node
,
3704 ffecom_2 (ARRAY_REF
,
3705 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree
))),
3708 ffecom_2 (ARRAY_REF
,
3709 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree
))),
3715 item
= build_tree_list (NULL_TREE
, left_tree
);
3716 TREE_CHAIN (item
) = build_tree_list (NULL_TREE
, right_tree
);
3717 TREE_CHAIN (TREE_CHAIN (item
)) = build_tree_list (NULL_TREE
,
3719 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item
)))
3720 = build_tree_list (NULL_TREE
, right_length
);
3721 item
= ffecom_call_gfrt (FFECOM_gfrtCMP
, item
, NULL_TREE
);
3722 item
= ffecom_2 (code
, integer_type_node
,
3724 convert (TREE_TYPE (item
),
3725 integer_zero_node
));
3727 item
= convert (tree_type
, item
);
3733 assert ("relational bad basictype" == NULL
);
3735 case FFEINFO_basictypeANY
:
3736 return error_mark_node
;
3740 case FFEBLD_opPERCENT_LOC
:
3741 item
= ffecom_arg_ptr_to_expr (ffebld_left (expr
), &list
);
3742 return convert (tree_type
, item
);
3744 case FFEBLD_opPERCENT_VAL
:
3745 item
= ffecom_arg_expr (ffebld_left (expr
), &list
);
3746 return convert (tree_type
, item
);
3750 case FFEBLD_opBOUNDS
:
3751 case FFEBLD_opREPEAT
:
3752 case FFEBLD_opLABTER
:
3753 case FFEBLD_opLABTOK
:
3754 case FFEBLD_opIMPDO
:
3755 case FFEBLD_opCONCATENATE
:
3756 case FFEBLD_opSUBSTR
:
3758 assert ("bad op" == NULL
);
3761 return error_mark_node
;
3765 assert ("didn't think anything got here anymore!!" == NULL
);
3767 switch (ffebld_arity (expr
))
3770 TREE_OPERAND (item
, 0) = ffecom_expr (ffebld_left (expr
));
3771 TREE_OPERAND (item
, 1) = ffecom_expr (ffebld_right (expr
));
3772 if (TREE_OPERAND (item
, 0) == error_mark_node
3773 || TREE_OPERAND (item
, 1) == error_mark_node
)
3774 return error_mark_node
;
3778 TREE_OPERAND (item
, 0) = ffecom_expr (ffebld_left (expr
));
3779 if (TREE_OPERAND (item
, 0) == error_mark_node
)
3780 return error_mark_node
;
3791 /* Returns the tree that does the intrinsic invocation.
3793 Note: this function applies only to intrinsics returning
3794 CHARACTER*1 or non-CHARACTER results, and to intrinsic
3798 ffecom_expr_intrinsic_ (ffebld expr
, tree dest_tree
,
3799 ffebld dest
, bool *dest_used
)
3802 tree saved_expr1
; /* For those who need it. */
3803 tree saved_expr2
; /* For those who need it. */
3804 ffeinfoBasictype bt
;
3808 tree real_type
; /* REAL type corresponding to COMPLEX. */
3810 ffebld list
= ffebld_right (expr
); /* List of (some) args. */
3811 ffebld arg1
; /* For handy reference. */
3814 ffeintrinImp codegen_imp
;
3817 assert (ffebld_op (ffebld_left (expr
)) == FFEBLD_opSYMTER
);
3819 if (dest_used
!= NULL
)
3822 bt
= ffeinfo_basictype (ffebld_info (expr
));
3823 kt
= ffeinfo_kindtype (ffebld_info (expr
));
3824 tree_type
= ffecom_tree_type
[bt
][kt
];
3828 arg1
= ffebld_head (list
);
3829 if (arg1
!= NULL
&& ffebld_op (arg1
) == FFEBLD_opANY
)
3830 return error_mark_node
;
3831 if ((list
= ffebld_trail (list
)) != NULL
)
3833 arg2
= ffebld_head (list
);
3834 if (arg2
!= NULL
&& ffebld_op (arg2
) == FFEBLD_opANY
)
3835 return error_mark_node
;
3836 if ((list
= ffebld_trail (list
)) != NULL
)
3838 arg3
= ffebld_head (list
);
3839 if (arg3
!= NULL
&& ffebld_op (arg3
) == FFEBLD_opANY
)
3840 return error_mark_node
;
3849 arg1
= arg2
= arg3
= NULL
;
3851 /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3
3852 args. This is used by the MAX/MIN expansions. */
3855 arg1_type
= ffecom_tree_type
3856 [ffeinfo_basictype (ffebld_info (arg1
))]
3857 [ffeinfo_kindtype (ffebld_info (arg1
))];
3859 arg1_type
= NULL_TREE
; /* Really not needed, but might catch bugs
3862 /* There are several ways for each of the cases in the following switch
3863 statements to exit (from simplest to use to most complicated):
3865 break; (when expr_tree == NULL)
3867 A standard call is made to the specific intrinsic just as if it had been
3868 passed in as a dummy procedure and called as any old procedure. This
3869 method can produce slower code but in some cases it's the easiest way for
3870 now. However, if a (presumably faster) direct call is available,
3871 that is used, so this is the easiest way in many more cases now.
3873 gfrt = FFECOM_gfrtWHATEVER;
3876 gfrt contains the gfrt index of a library function to call, passing the
3877 argument(s) by value rather than by reference. Used when a more
3878 careful choice of library function is needed than that provided
3879 by the vanilla `break;'.
3883 The expr_tree has been completely set up and is ready to be returned
3884 as is. No further actions are taken. Use this when the tree is not
3885 in the simple form for one of the arity_n labels. */
3887 /* For info on how the switch statement cases were written, see the files
3888 enclosed in comments below the switch statement. */
3890 codegen_imp
= ffebld_symter_implementation (ffebld_left (expr
));
3891 gfrt
= ffeintrin_gfrt_direct (codegen_imp
);
3892 if (gfrt
== FFECOM_gfrt
)
3893 gfrt
= ffeintrin_gfrt_indirect (codegen_imp
);
3895 switch (codegen_imp
)
3897 case FFEINTRIN_impABS
:
3898 case FFEINTRIN_impCABS
:
3899 case FFEINTRIN_impCDABS
:
3900 case FFEINTRIN_impDABS
:
3901 case FFEINTRIN_impIABS
:
3902 if (ffeinfo_basictype (ffebld_info (arg1
))
3903 == FFEINFO_basictypeCOMPLEX
)
3905 if (kt
== FFEINFO_kindtypeREAL1
)
3906 gfrt
= FFECOM_gfrtCABS
;
3907 else if (kt
== FFEINFO_kindtypeREAL2
)
3908 gfrt
= FFECOM_gfrtCDABS
;
3911 return ffecom_1 (ABS_EXPR
, tree_type
,
3912 convert (tree_type
, ffecom_expr (arg1
)));
3914 case FFEINTRIN_impACOS
:
3915 case FFEINTRIN_impDACOS
:
3918 case FFEINTRIN_impAIMAG
:
3919 case FFEINTRIN_impDIMAG
:
3920 case FFEINTRIN_impIMAGPART
:
3921 if (TREE_CODE (arg1_type
) == COMPLEX_TYPE
)
3922 arg1_type
= TREE_TYPE (arg1_type
);
3924 arg1_type
= TREE_TYPE (TYPE_FIELDS (arg1_type
));
3928 ffecom_1 (IMAGPART_EXPR
, arg1_type
,
3929 ffecom_expr (arg1
)));
3931 case FFEINTRIN_impAINT
:
3932 case FFEINTRIN_impDINT
:
3934 /* ~~Someday implement FIX_TRUNC_EXPR yielding same type as arg. */
3935 return ffecom_1 (FIX_TRUNC_EXPR
, tree_type
, ffecom_expr (arg1
));
3936 #else /* in the meantime, must use floor to avoid range problems with ints */
3937 /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */
3938 saved_expr1
= ffecom_save_tree (ffecom_expr (arg1
));
3941 ffecom_3 (COND_EXPR
, double_type_node
,
3943 (ffecom_2 (GE_EXPR
, integer_type_node
,
3946 ffecom_float_zero_
))),
3947 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR
,
3948 build_tree_list (NULL_TREE
,
3949 convert (double_type_node
,
3952 ffecom_1 (NEGATE_EXPR
, double_type_node
,
3953 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR
,
3954 build_tree_list (NULL_TREE
,
3955 convert (double_type_node
,
3956 ffecom_1 (NEGATE_EXPR
,
3964 case FFEINTRIN_impANINT
:
3965 case FFEINTRIN_impDNINT
:
3966 #if 0 /* This way of doing it won't handle real
3967 numbers of large magnitudes. */
3968 saved_expr1
= ffecom_save_tree (ffecom_expr (arg1
));
3969 expr_tree
= convert (tree_type
,
3970 convert (integer_type_node
,
3971 ffecom_3 (COND_EXPR
, tree_type
,
3976 ffecom_float_zero_
)),
3977 ffecom_2 (PLUS_EXPR
,
3980 ffecom_float_half_
),
3981 ffecom_2 (MINUS_EXPR
,
3984 ffecom_float_half_
))));
3986 #else /* So we instead call floor. */
3987 /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */
3988 saved_expr1
= ffecom_save_tree (ffecom_expr (arg1
));
3991 ffecom_3 (COND_EXPR
, double_type_node
,
3993 (ffecom_2 (GE_EXPR
, integer_type_node
,
3996 ffecom_float_zero_
))),
3997 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR
,
3998 build_tree_list (NULL_TREE
,
3999 convert (double_type_node
,
4000 ffecom_2 (PLUS_EXPR
,
4004 ffecom_float_half_
)))),
4006 ffecom_1 (NEGATE_EXPR
, double_type_node
,
4007 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR
,
4008 build_tree_list (NULL_TREE
,
4009 convert (double_type_node
,
4010 ffecom_2 (MINUS_EXPR
,
4013 ffecom_float_half_
),
4020 case FFEINTRIN_impASIN
:
4021 case FFEINTRIN_impDASIN
:
4022 case FFEINTRIN_impATAN
:
4023 case FFEINTRIN_impDATAN
:
4024 case FFEINTRIN_impATAN2
:
4025 case FFEINTRIN_impDATAN2
:
4028 case FFEINTRIN_impCHAR
:
4029 case FFEINTRIN_impACHAR
:
4030 tempvar
= ffebld_nonter_hook (expr
);
4033 tree tmv
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar
)));
4035 expr_tree
= ffecom_modify (tmv
,
4036 ffecom_2 (ARRAY_REF
, tmv
, tempvar
,
4038 convert (tmv
, ffecom_expr (arg1
)));
4040 expr_tree
= ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (tempvar
),
4043 expr_tree
= ffecom_1 (ADDR_EXPR
,
4044 build_pointer_type (TREE_TYPE (expr_tree
)),
4048 case FFEINTRIN_impCMPLX
:
4049 case FFEINTRIN_impDCMPLX
:
4052 convert (tree_type
, ffecom_expr (arg1
));
4054 real_type
= ffecom_tree_type
[FFEINFO_basictypeREAL
][kt
];
4056 ffecom_2 (COMPLEX_EXPR
, tree_type
,
4057 convert (real_type
, ffecom_expr (arg1
)),
4059 ffecom_expr (arg2
)));
4061 case FFEINTRIN_impCOMPLEX
:
4063 ffecom_2 (COMPLEX_EXPR
, tree_type
,
4065 ffecom_expr (arg2
));
4067 case FFEINTRIN_impCONJG
:
4068 case FFEINTRIN_impDCONJG
:
4072 real_type
= ffecom_tree_type
[FFEINFO_basictypeREAL
][kt
];
4073 arg1_tree
= ffecom_save_tree (ffecom_expr (arg1
));
4075 ffecom_2 (COMPLEX_EXPR
, tree_type
,
4076 ffecom_1 (REALPART_EXPR
, real_type
, arg1_tree
),
4077 ffecom_1 (NEGATE_EXPR
, real_type
,
4078 ffecom_1 (IMAGPART_EXPR
, real_type
, arg1_tree
)));
4081 case FFEINTRIN_impCOS
:
4082 case FFEINTRIN_impCCOS
:
4083 case FFEINTRIN_impCDCOS
:
4084 case FFEINTRIN_impDCOS
:
4085 if (bt
== FFEINFO_basictypeCOMPLEX
)
4087 if (kt
== FFEINFO_kindtypeREAL1
)
4088 gfrt
= FFECOM_gfrtCCOS
; /* Overlapping result okay. */
4089 else if (kt
== FFEINFO_kindtypeREAL2
)
4090 gfrt
= FFECOM_gfrtCDCOS
; /* Overlapping result okay. */
4094 case FFEINTRIN_impCOSH
:
4095 case FFEINTRIN_impDCOSH
:
4098 case FFEINTRIN_impDBLE
:
4099 case FFEINTRIN_impDFLOAT
:
4100 case FFEINTRIN_impDREAL
:
4101 case FFEINTRIN_impFLOAT
:
4102 case FFEINTRIN_impIDINT
:
4103 case FFEINTRIN_impIFIX
:
4104 case FFEINTRIN_impINT2
:
4105 case FFEINTRIN_impINT8
:
4106 case FFEINTRIN_impINT
:
4107 case FFEINTRIN_impLONG
:
4108 case FFEINTRIN_impREAL
:
4109 case FFEINTRIN_impSHORT
:
4110 case FFEINTRIN_impSNGL
:
4111 return convert (tree_type
, ffecom_expr (arg1
));
4113 case FFEINTRIN_impDIM
:
4114 case FFEINTRIN_impDDIM
:
4115 case FFEINTRIN_impIDIM
:
4116 saved_expr1
= ffecom_save_tree (convert (tree_type
,
4117 ffecom_expr (arg1
)));
4118 saved_expr2
= ffecom_save_tree (convert (tree_type
,
4119 ffecom_expr (arg2
)));
4121 ffecom_3 (COND_EXPR
, tree_type
,
4123 (ffecom_2 (GT_EXPR
, integer_type_node
,
4126 ffecom_2 (MINUS_EXPR
, tree_type
,
4129 convert (tree_type
, ffecom_float_zero_
));
4131 case FFEINTRIN_impDPROD
:
4133 ffecom_2 (MULT_EXPR
, tree_type
,
4134 convert (tree_type
, ffecom_expr (arg1
)),
4135 convert (tree_type
, ffecom_expr (arg2
)));
4137 case FFEINTRIN_impEXP
:
4138 case FFEINTRIN_impCDEXP
:
4139 case FFEINTRIN_impCEXP
:
4140 case FFEINTRIN_impDEXP
:
4141 if (bt
== FFEINFO_basictypeCOMPLEX
)
4143 if (kt
== FFEINFO_kindtypeREAL1
)
4144 gfrt
= FFECOM_gfrtCEXP
; /* Overlapping result okay. */
4145 else if (kt
== FFEINFO_kindtypeREAL2
)
4146 gfrt
= FFECOM_gfrtCDEXP
; /* Overlapping result okay. */
4150 case FFEINTRIN_impICHAR
:
4151 case FFEINTRIN_impIACHAR
:
4152 #if 0 /* The simple approach. */
4153 ffecom_char_args_ (&expr_tree
, &saved_expr1
/* Ignored */ , arg1
);
4155 = ffecom_1 (INDIRECT_REF
,
4156 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree
))),
4159 = ffecom_2 (ARRAY_REF
,
4160 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree
))),
4163 return convert (tree_type
, expr_tree
);
4164 #else /* The more interesting (and more optimal) approach. */
4165 expr_tree
= ffecom_intrinsic_ichar_ (tree_type
, arg1
, &saved_expr1
);
4166 expr_tree
= ffecom_3 (COND_EXPR
, tree_type
,
4169 convert (tree_type
, integer_zero_node
));
4173 case FFEINTRIN_impINDEX
:
4176 case FFEINTRIN_impLEN
:
4178 break; /* The simple approach. */
4180 return ffecom_intrinsic_len_ (arg1
); /* The more optimal approach. */
4183 case FFEINTRIN_impLGE
:
4184 case FFEINTRIN_impLGT
:
4185 case FFEINTRIN_impLLE
:
4186 case FFEINTRIN_impLLT
:
4189 case FFEINTRIN_impLOG
:
4190 case FFEINTRIN_impALOG
:
4191 case FFEINTRIN_impCDLOG
:
4192 case FFEINTRIN_impCLOG
:
4193 case FFEINTRIN_impDLOG
:
4194 if (bt
== FFEINFO_basictypeCOMPLEX
)
4196 if (kt
== FFEINFO_kindtypeREAL1
)
4197 gfrt
= FFECOM_gfrtCLOG
; /* Overlapping result okay. */
4198 else if (kt
== FFEINFO_kindtypeREAL2
)
4199 gfrt
= FFECOM_gfrtCDLOG
; /* Overlapping result okay. */
4203 case FFEINTRIN_impLOG10
:
4204 case FFEINTRIN_impALOG10
:
4205 case FFEINTRIN_impDLOG10
:
4206 if (gfrt
!= FFECOM_gfrt
)
4207 break; /* Already picked one, stick with it. */
4209 if (kt
== FFEINFO_kindtypeREAL1
)
4210 /* We used to call FFECOM_gfrtALOG10 here. */
4211 gfrt
= FFECOM_gfrtL_LOG10
;
4212 else if (kt
== FFEINFO_kindtypeREAL2
)
4213 /* We used to call FFECOM_gfrtDLOG10 here. */
4214 gfrt
= FFECOM_gfrtL_LOG10
;
4217 case FFEINTRIN_impMAX
:
4218 case FFEINTRIN_impAMAX0
:
4219 case FFEINTRIN_impAMAX1
:
4220 case FFEINTRIN_impDMAX1
:
4221 case FFEINTRIN_impMAX0
:
4222 case FFEINTRIN_impMAX1
:
4223 if (bt
!= ffeinfo_basictype (ffebld_info (arg1
)))
4224 arg1_type
= ffecom_widest_expr_type_ (ffebld_right (expr
));
4226 arg1_type
= tree_type
;
4227 expr_tree
= ffecom_2 (MAX_EXPR
, arg1_type
,
4228 convert (arg1_type
, ffecom_expr (arg1
)),
4229 convert (arg1_type
, ffecom_expr (arg2
)));
4230 for (; list
!= NULL
; list
= ffebld_trail (list
))
4232 if ((ffebld_head (list
) == NULL
)
4233 || (ffebld_op (ffebld_head (list
)) == FFEBLD_opANY
))
4235 expr_tree
= ffecom_2 (MAX_EXPR
, arg1_type
,
4238 ffecom_expr (ffebld_head (list
))));
4240 return convert (tree_type
, expr_tree
);
4242 case FFEINTRIN_impMIN
:
4243 case FFEINTRIN_impAMIN0
:
4244 case FFEINTRIN_impAMIN1
:
4245 case FFEINTRIN_impDMIN1
:
4246 case FFEINTRIN_impMIN0
:
4247 case FFEINTRIN_impMIN1
:
4248 if (bt
!= ffeinfo_basictype (ffebld_info (arg1
)))
4249 arg1_type
= ffecom_widest_expr_type_ (ffebld_right (expr
));
4251 arg1_type
= tree_type
;
4252 expr_tree
= ffecom_2 (MIN_EXPR
, arg1_type
,
4253 convert (arg1_type
, ffecom_expr (arg1
)),
4254 convert (arg1_type
, ffecom_expr (arg2
)));
4255 for (; list
!= NULL
; list
= ffebld_trail (list
))
4257 if ((ffebld_head (list
) == NULL
)
4258 || (ffebld_op (ffebld_head (list
)) == FFEBLD_opANY
))
4260 expr_tree
= ffecom_2 (MIN_EXPR
, arg1_type
,
4263 ffecom_expr (ffebld_head (list
))));
4265 return convert (tree_type
, expr_tree
);
4267 case FFEINTRIN_impMOD
:
4268 case FFEINTRIN_impAMOD
:
4269 case FFEINTRIN_impDMOD
:
4270 if (bt
!= FFEINFO_basictypeREAL
)
4271 return ffecom_2 (TRUNC_MOD_EXPR
, tree_type
,
4272 convert (tree_type
, ffecom_expr (arg1
)),
4273 convert (tree_type
, ffecom_expr (arg2
)));
4275 if (kt
== FFEINFO_kindtypeREAL1
)
4276 /* We used to call FFECOM_gfrtAMOD here. */
4277 gfrt
= FFECOM_gfrtL_FMOD
;
4278 else if (kt
== FFEINFO_kindtypeREAL2
)
4279 /* We used to call FFECOM_gfrtDMOD here. */
4280 gfrt
= FFECOM_gfrtL_FMOD
;
4283 case FFEINTRIN_impNINT
:
4284 case FFEINTRIN_impIDNINT
:
4286 /* ~~Ideally FIX_ROUND_EXPR would be implemented, but it ain't yet. */
4287 return ffecom_1 (FIX_ROUND_EXPR
, tree_type
, ffecom_expr (arg1
));
4289 /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */
4290 saved_expr1
= ffecom_save_tree (ffecom_expr (arg1
));
4292 convert (ffecom_integer_type_node
,
4293 ffecom_3 (COND_EXPR
, arg1_type
,
4295 (ffecom_2 (GE_EXPR
, integer_type_node
,
4298 ffecom_float_zero_
))),
4299 ffecom_2 (PLUS_EXPR
, arg1_type
,
4302 ffecom_float_half_
)),
4303 ffecom_2 (MINUS_EXPR
, arg1_type
,
4306 ffecom_float_half_
))));
4309 case FFEINTRIN_impSIGN
:
4310 case FFEINTRIN_impDSIGN
:
4311 case FFEINTRIN_impISIGN
:
4313 tree arg2_tree
= ffecom_expr (arg2
);
4317 (ffecom_1 (ABS_EXPR
, tree_type
,
4319 ffecom_expr (arg1
))));
4321 = ffecom_3 (COND_EXPR
, tree_type
,
4323 (ffecom_2 (GE_EXPR
, integer_type_node
,
4325 convert (TREE_TYPE (arg2_tree
),
4326 integer_zero_node
))),
4328 ffecom_1 (NEGATE_EXPR
, tree_type
, saved_expr1
));
4329 /* Make sure SAVE_EXPRs get referenced early enough. */
4331 = ffecom_2 (COMPOUND_EXPR
, tree_type
,
4332 convert (void_type_node
, saved_expr1
),
4337 case FFEINTRIN_impSIN
:
4338 case FFEINTRIN_impCDSIN
:
4339 case FFEINTRIN_impCSIN
:
4340 case FFEINTRIN_impDSIN
:
4341 if (bt
== FFEINFO_basictypeCOMPLEX
)
4343 if (kt
== FFEINFO_kindtypeREAL1
)
4344 gfrt
= FFECOM_gfrtCSIN
; /* Overlapping result okay. */
4345 else if (kt
== FFEINFO_kindtypeREAL2
)
4346 gfrt
= FFECOM_gfrtCDSIN
; /* Overlapping result okay. */
4350 case FFEINTRIN_impSINH
:
4351 case FFEINTRIN_impDSINH
:
4354 case FFEINTRIN_impSQRT
:
4355 case FFEINTRIN_impCDSQRT
:
4356 case FFEINTRIN_impCSQRT
:
4357 case FFEINTRIN_impDSQRT
:
4358 if (bt
== FFEINFO_basictypeCOMPLEX
)
4360 if (kt
== FFEINFO_kindtypeREAL1
)
4361 gfrt
= FFECOM_gfrtCSQRT
; /* Overlapping result okay. */
4362 else if (kt
== FFEINFO_kindtypeREAL2
)
4363 gfrt
= FFECOM_gfrtCDSQRT
; /* Overlapping result okay. */
4367 case FFEINTRIN_impTAN
:
4368 case FFEINTRIN_impDTAN
:
4369 case FFEINTRIN_impTANH
:
4370 case FFEINTRIN_impDTANH
:
4373 case FFEINTRIN_impREALPART
:
4374 if (TREE_CODE (arg1_type
) == COMPLEX_TYPE
)
4375 arg1_type
= TREE_TYPE (arg1_type
);
4377 arg1_type
= TREE_TYPE (TYPE_FIELDS (arg1_type
));
4381 ffecom_1 (REALPART_EXPR
, arg1_type
,
4382 ffecom_expr (arg1
)));
4384 case FFEINTRIN_impIAND
:
4385 case FFEINTRIN_impAND
:
4386 return ffecom_2 (BIT_AND_EXPR
, tree_type
,
4388 ffecom_expr (arg1
)),
4390 ffecom_expr (arg2
)));
4392 case FFEINTRIN_impIOR
:
4393 case FFEINTRIN_impOR
:
4394 return ffecom_2 (BIT_IOR_EXPR
, tree_type
,
4396 ffecom_expr (arg1
)),
4398 ffecom_expr (arg2
)));
4400 case FFEINTRIN_impIEOR
:
4401 case FFEINTRIN_impXOR
:
4402 return ffecom_2 (BIT_XOR_EXPR
, tree_type
,
4404 ffecom_expr (arg1
)),
4406 ffecom_expr (arg2
)));
4408 case FFEINTRIN_impLSHIFT
:
4409 return ffecom_2 (LSHIFT_EXPR
, tree_type
,
4411 convert (integer_type_node
,
4412 ffecom_expr (arg2
)));
4414 case FFEINTRIN_impRSHIFT
:
4415 return ffecom_2 (RSHIFT_EXPR
, tree_type
,
4417 convert (integer_type_node
,
4418 ffecom_expr (arg2
)));
4420 case FFEINTRIN_impNOT
:
4421 return ffecom_1 (BIT_NOT_EXPR
, tree_type
, ffecom_expr (arg1
));
4423 case FFEINTRIN_impBIT_SIZE
:
4424 return convert (tree_type
, TYPE_SIZE (arg1_type
));
4426 case FFEINTRIN_impBTEST
:
4428 ffetargetLogical1 target_true
;
4429 ffetargetLogical1 target_false
;
4433 ffetarget_logical1 (&target_true
, TRUE
);
4434 ffetarget_logical1 (&target_false
, FALSE
);
4435 if (target_true
== 1)
4436 true_tree
= convert (tree_type
, integer_one_node
);
4438 true_tree
= convert (tree_type
, build_int_2 (target_true
, 0));
4439 if (target_false
== 0)
4440 false_tree
= convert (tree_type
, integer_zero_node
);
4442 false_tree
= convert (tree_type
, build_int_2 (target_false
, 0));
4445 ffecom_3 (COND_EXPR
, tree_type
,
4447 (ffecom_2 (EQ_EXPR
, integer_type_node
,
4448 ffecom_2 (BIT_AND_EXPR
, arg1_type
,
4450 ffecom_2 (LSHIFT_EXPR
, arg1_type
,
4453 convert (integer_type_node
,
4454 ffecom_expr (arg2
)))),
4456 integer_zero_node
))),
4461 case FFEINTRIN_impIBCLR
:
4463 ffecom_2 (BIT_AND_EXPR
, tree_type
,
4465 ffecom_1 (BIT_NOT_EXPR
, tree_type
,
4466 ffecom_2 (LSHIFT_EXPR
, tree_type
,
4469 convert (integer_type_node
,
4470 ffecom_expr (arg2
)))));
4472 case FFEINTRIN_impIBITS
:
4474 tree arg3_tree
= ffecom_save_tree (convert (integer_type_node
,
4475 ffecom_expr (arg3
)));
4477 = ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][kt
];
4480 = ffecom_2 (BIT_AND_EXPR
, tree_type
,
4481 ffecom_2 (RSHIFT_EXPR
, tree_type
,
4483 convert (integer_type_node
,
4484 ffecom_expr (arg2
))),
4486 ffecom_2 (RSHIFT_EXPR
, uns_type
,
4487 ffecom_1 (BIT_NOT_EXPR
,
4490 integer_zero_node
)),
4491 ffecom_2 (MINUS_EXPR
,
4493 TYPE_SIZE (uns_type
),
4495 /* Fix up, because the RSHIFT_EXPR above can't shift over TYPE_SIZE. */
4497 = ffecom_3 (COND_EXPR
, tree_type
,
4499 (ffecom_2 (NE_EXPR
, integer_type_node
,
4501 integer_zero_node
)),
4503 convert (tree_type
, integer_zero_node
));
4507 case FFEINTRIN_impIBSET
:
4509 ffecom_2 (BIT_IOR_EXPR
, tree_type
,
4511 ffecom_2 (LSHIFT_EXPR
, tree_type
,
4512 convert (tree_type
, integer_one_node
),
4513 convert (integer_type_node
,
4514 ffecom_expr (arg2
))));
4516 case FFEINTRIN_impISHFT
:
4518 tree arg1_tree
= ffecom_save_tree (ffecom_expr (arg1
));
4519 tree arg2_tree
= ffecom_save_tree (convert (integer_type_node
,
4520 ffecom_expr (arg2
)));
4522 = ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][kt
];
4525 = ffecom_3 (COND_EXPR
, tree_type
,
4527 (ffecom_2 (GE_EXPR
, integer_type_node
,
4529 integer_zero_node
)),
4530 ffecom_2 (LSHIFT_EXPR
, tree_type
,
4534 ffecom_2 (RSHIFT_EXPR
, uns_type
,
4535 convert (uns_type
, arg1_tree
),
4536 ffecom_1 (NEGATE_EXPR
,
4539 /* Fix up, because {L|R}SHIFT_EXPR don't go over TYPE_SIZE bounds. */
4541 = ffecom_3 (COND_EXPR
, tree_type
,
4543 (ffecom_2 (NE_EXPR
, integer_type_node
,
4547 TYPE_SIZE (uns_type
))),
4549 convert (tree_type
, integer_zero_node
));
4550 /* Make sure SAVE_EXPRs get referenced early enough. */
4552 = ffecom_2 (COMPOUND_EXPR
, tree_type
,
4553 convert (void_type_node
, arg1_tree
),
4554 ffecom_2 (COMPOUND_EXPR
, tree_type
,
4555 convert (void_type_node
, arg2_tree
),
4560 case FFEINTRIN_impISHFTC
:
4562 tree arg1_tree
= ffecom_save_tree (ffecom_expr (arg1
));
4563 tree arg2_tree
= ffecom_save_tree (convert (integer_type_node
,
4564 ffecom_expr (arg2
)));
4565 tree arg3_tree
= (arg3
== NULL
) ? TYPE_SIZE (tree_type
)
4566 : ffecom_save_tree (convert (integer_type_node
, ffecom_expr (arg3
)));
4572 = ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][kt
];
4575 = ffecom_2 (LSHIFT_EXPR
, tree_type
,
4576 ffecom_1 (BIT_NOT_EXPR
, tree_type
,
4577 convert (tree_type
, integer_zero_node
)),
4579 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
4581 = ffecom_3 (COND_EXPR
, tree_type
,
4583 (ffecom_2 (NE_EXPR
, integer_type_node
,
4585 TYPE_SIZE (uns_type
))),
4587 convert (tree_type
, integer_zero_node
));
4588 mask_arg1
= ffecom_save_tree (mask_arg1
);
4590 = ffecom_2 (BIT_AND_EXPR
, tree_type
,
4592 ffecom_1 (BIT_NOT_EXPR
, tree_type
,
4594 masked_arg1
= ffecom_save_tree (masked_arg1
);
4596 = ffecom_2 (BIT_IOR_EXPR
, tree_type
,
4598 ffecom_2 (RSHIFT_EXPR
, uns_type
,
4599 convert (uns_type
, masked_arg1
),
4600 ffecom_1 (NEGATE_EXPR
,
4603 ffecom_2 (LSHIFT_EXPR
, tree_type
,
4605 ffecom_2 (PLUS_EXPR
, integer_type_node
,
4609 = ffecom_2 (BIT_IOR_EXPR
, tree_type
,
4610 ffecom_2 (LSHIFT_EXPR
, tree_type
,
4614 ffecom_2 (RSHIFT_EXPR
, uns_type
,
4615 convert (uns_type
, masked_arg1
),
4616 ffecom_2 (MINUS_EXPR
,
4621 = ffecom_3 (COND_EXPR
, tree_type
,
4623 (ffecom_2 (LT_EXPR
, integer_type_node
,
4625 integer_zero_node
)),
4629 = ffecom_2 (BIT_IOR_EXPR
, tree_type
,
4630 ffecom_2 (BIT_AND_EXPR
, tree_type
,
4633 ffecom_2 (BIT_AND_EXPR
, tree_type
,
4634 ffecom_1 (BIT_NOT_EXPR
, tree_type
,
4638 = ffecom_3 (COND_EXPR
, tree_type
,
4640 (ffecom_2 (TRUTH_ORIF_EXPR
, integer_type_node
,
4641 ffecom_2 (EQ_EXPR
, integer_type_node
,
4646 ffecom_2 (EQ_EXPR
, integer_type_node
,
4648 integer_zero_node
))),
4651 /* Make sure SAVE_EXPRs get referenced early enough. */
4653 = ffecom_2 (COMPOUND_EXPR
, tree_type
,
4654 convert (void_type_node
, arg1_tree
),
4655 ffecom_2 (COMPOUND_EXPR
, tree_type
,
4656 convert (void_type_node
, arg2_tree
),
4657 ffecom_2 (COMPOUND_EXPR
, tree_type
,
4658 convert (void_type_node
,
4660 ffecom_2 (COMPOUND_EXPR
, tree_type
,
4661 convert (void_type_node
,
4665 = ffecom_2 (COMPOUND_EXPR
, tree_type
,
4666 convert (void_type_node
,
4672 case FFEINTRIN_impLOC
:
4674 tree arg1_tree
= ffecom_expr (arg1
);
4677 = convert (tree_type
,
4678 ffecom_1 (ADDR_EXPR
,
4679 build_pointer_type (TREE_TYPE (arg1_tree
)),
4684 case FFEINTRIN_impMVBITS
:
4689 ffebld arg4
= ffebld_head (ffebld_trail (list
));
4692 ffebld arg5
= ffebld_head (ffebld_trail (ffebld_trail (list
)));
4696 tree arg5_plus_arg3
;
4698 arg2_tree
= convert (integer_type_node
,
4699 ffecom_expr (arg2
));
4700 arg3_tree
= ffecom_save_tree (convert (integer_type_node
,
4701 ffecom_expr (arg3
)));
4702 arg4_tree
= ffecom_expr_rw (NULL_TREE
, arg4
);
4703 arg4_type
= TREE_TYPE (arg4_tree
);
4705 arg1_tree
= ffecom_save_tree (convert (arg4_type
,
4706 ffecom_expr (arg1
)));
4708 arg5_tree
= ffecom_save_tree (convert (integer_type_node
,
4709 ffecom_expr (arg5
)));
4712 = ffecom_2 (LSHIFT_EXPR
, arg4_type
,
4713 ffecom_2 (BIT_AND_EXPR
, arg4_type
,
4714 ffecom_2 (RSHIFT_EXPR
, arg4_type
,
4717 ffecom_1 (BIT_NOT_EXPR
, arg4_type
,
4718 ffecom_2 (LSHIFT_EXPR
, arg4_type
,
4719 ffecom_1 (BIT_NOT_EXPR
,
4723 integer_zero_node
)),
4727 = ffecom_save_tree (ffecom_2 (PLUS_EXPR
, arg4_type
,
4731 = ffecom_2 (LSHIFT_EXPR
, arg4_type
,
4732 ffecom_1 (BIT_NOT_EXPR
, arg4_type
,
4734 integer_zero_node
)),
4736 /* Fix up, because LSHIFT_EXPR above can't shift over TYPE_SIZE. */
4738 = ffecom_3 (COND_EXPR
, arg4_type
,
4740 (ffecom_2 (NE_EXPR
, integer_type_node
,
4742 convert (TREE_TYPE (arg5_plus_arg3
),
4743 TYPE_SIZE (arg4_type
)))),
4745 convert (arg4_type
, integer_zero_node
));
4747 = ffecom_2 (BIT_AND_EXPR
, arg4_type
,
4749 ffecom_2 (BIT_IOR_EXPR
, arg4_type
,
4751 ffecom_1 (BIT_NOT_EXPR
, arg4_type
,
4752 ffecom_2 (LSHIFT_EXPR
, arg4_type
,
4753 ffecom_1 (BIT_NOT_EXPR
,
4757 integer_zero_node
)),
4760 = ffecom_2 (BIT_IOR_EXPR
, arg4_type
,
4763 /* Fix up (twice), because LSHIFT_EXPR above
4764 can't shift over TYPE_SIZE. */
4766 = ffecom_3 (COND_EXPR
, arg4_type
,
4768 (ffecom_2 (NE_EXPR
, integer_type_node
,
4770 convert (TREE_TYPE (arg3_tree
),
4771 integer_zero_node
))),
4775 = ffecom_3 (COND_EXPR
, arg4_type
,
4777 (ffecom_2 (NE_EXPR
, integer_type_node
,
4779 convert (TREE_TYPE (arg3_tree
),
4780 TYPE_SIZE (arg4_type
)))),
4784 = ffecom_2s (MODIFY_EXPR
, void_type_node
,
4787 /* Make sure SAVE_EXPRs get referenced early enough. */
4789 = ffecom_2 (COMPOUND_EXPR
, void_type_node
,
4791 ffecom_2 (COMPOUND_EXPR
, void_type_node
,
4793 ffecom_2 (COMPOUND_EXPR
, void_type_node
,
4795 ffecom_2 (COMPOUND_EXPR
, void_type_node
,
4799 = ffecom_2 (COMPOUND_EXPR
, void_type_node
,
4806 case FFEINTRIN_impDERF
:
4807 case FFEINTRIN_impERF
:
4808 case FFEINTRIN_impDERFC
:
4809 case FFEINTRIN_impERFC
:
4812 case FFEINTRIN_impIARGC
:
4813 /* extern int xargc; i__1 = xargc - 1; */
4814 expr_tree
= ffecom_2 (MINUS_EXPR
, TREE_TYPE (ffecom_tree_xargc_
),
4816 convert (TREE_TYPE (ffecom_tree_xargc_
),
4820 case FFEINTRIN_impSIGNAL_func
:
4821 case FFEINTRIN_impSIGNAL_subr
:
4827 arg1_tree
= convert (ffecom_f2c_integer_type_node
,
4828 ffecom_expr (arg1
));
4829 arg1_tree
= ffecom_1 (ADDR_EXPR
,
4830 build_pointer_type (TREE_TYPE (arg1_tree
)),
4833 /* Pass procedure as a pointer to it, anything else by value. */
4834 if (ffeinfo_kind (ffebld_info (arg2
)) == FFEINFO_kindENTITY
)
4835 arg2_tree
= convert (integer_type_node
, ffecom_expr (arg2
));
4837 arg2_tree
= ffecom_ptr_to_expr (arg2
);
4838 arg2_tree
= convert (TREE_TYPE (null_pointer_node
),
4842 arg3_tree
= ffecom_expr_w (NULL_TREE
, arg3
);
4844 arg3_tree
= NULL_TREE
;
4846 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
4847 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
4848 TREE_CHAIN (arg1_tree
) = arg2_tree
;
4851 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
4852 ffecom_gfrt_kindtype (gfrt
),
4854 ((codegen_imp
== FFEINTRIN_impSIGNAL_subr
) ?
4858 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
4859 ffebld_nonter_hook (expr
));
4861 if (arg3_tree
!= NULL_TREE
)
4863 = ffecom_modify (NULL_TREE
, arg3_tree
,
4864 convert (TREE_TYPE (arg3_tree
),
4869 case FFEINTRIN_impALARM
:
4875 arg1_tree
= convert (ffecom_f2c_integer_type_node
,
4876 ffecom_expr (arg1
));
4877 arg1_tree
= ffecom_1 (ADDR_EXPR
,
4878 build_pointer_type (TREE_TYPE (arg1_tree
)),
4881 /* Pass procedure as a pointer to it, anything else by value. */
4882 if (ffeinfo_kind (ffebld_info (arg2
)) == FFEINFO_kindENTITY
)
4883 arg2_tree
= convert (integer_type_node
, ffecom_expr (arg2
));
4885 arg2_tree
= ffecom_ptr_to_expr (arg2
);
4886 arg2_tree
= convert (TREE_TYPE (null_pointer_node
),
4890 arg3_tree
= ffecom_expr_w (NULL_TREE
, arg3
);
4892 arg3_tree
= NULL_TREE
;
4894 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
4895 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
4896 TREE_CHAIN (arg1_tree
) = arg2_tree
;
4899 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
4900 ffecom_gfrt_kindtype (gfrt
),
4904 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
4905 ffebld_nonter_hook (expr
));
4907 if (arg3_tree
!= NULL_TREE
)
4909 = ffecom_modify (NULL_TREE
, arg3_tree
,
4910 convert (TREE_TYPE (arg3_tree
),
4915 case FFEINTRIN_impCHDIR_subr
:
4916 case FFEINTRIN_impFDATE_subr
:
4917 case FFEINTRIN_impFGET_subr
:
4918 case FFEINTRIN_impFPUT_subr
:
4919 case FFEINTRIN_impGETCWD_subr
:
4920 case FFEINTRIN_impHOSTNM_subr
:
4921 case FFEINTRIN_impSYSTEM_subr
:
4922 case FFEINTRIN_impUNLINK_subr
:
4924 tree arg1_len
= integer_zero_node
;
4928 arg1_tree
= ffecom_arg_ptr_to_expr (arg1
, &arg1_len
);
4931 arg2_tree
= ffecom_expr_w (NULL_TREE
, arg2
);
4933 arg2_tree
= NULL_TREE
;
4935 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
4936 arg1_len
= build_tree_list (NULL_TREE
, arg1_len
);
4937 TREE_CHAIN (arg1_tree
) = arg1_len
;
4940 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
4941 ffecom_gfrt_kindtype (gfrt
),
4945 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
4946 ffebld_nonter_hook (expr
));
4948 if (arg2_tree
!= NULL_TREE
)
4950 = ffecom_modify (NULL_TREE
, arg2_tree
,
4951 convert (TREE_TYPE (arg2_tree
),
4956 case FFEINTRIN_impEXIT
:
4960 expr_tree
= build_tree_list (NULL_TREE
,
4961 ffecom_1 (ADDR_EXPR
,
4963 (ffecom_integer_type_node
),
4964 integer_zero_node
));
4967 ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
4968 ffecom_gfrt_kindtype (gfrt
),
4972 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
4973 ffebld_nonter_hook (expr
));
4975 case FFEINTRIN_impFLUSH
:
4977 gfrt
= FFECOM_gfrtFLUSH
;
4979 gfrt
= FFECOM_gfrtFLUSH1
;
4982 case FFEINTRIN_impCHMOD_subr
:
4983 case FFEINTRIN_impLINK_subr
:
4984 case FFEINTRIN_impRENAME_subr
:
4985 case FFEINTRIN_impSYMLNK_subr
:
4987 tree arg1_len
= integer_zero_node
;
4989 tree arg2_len
= integer_zero_node
;
4993 arg1_tree
= ffecom_arg_ptr_to_expr (arg1
, &arg1_len
);
4994 arg2_tree
= ffecom_arg_ptr_to_expr (arg2
, &arg2_len
);
4996 arg3_tree
= ffecom_expr_w (NULL_TREE
, arg3
);
4998 arg3_tree
= NULL_TREE
;
5000 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
5001 arg1_len
= build_tree_list (NULL_TREE
, arg1_len
);
5002 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
5003 arg2_len
= build_tree_list (NULL_TREE
, arg2_len
);
5004 TREE_CHAIN (arg1_tree
) = arg2_tree
;
5005 TREE_CHAIN (arg2_tree
) = arg1_len
;
5006 TREE_CHAIN (arg1_len
) = arg2_len
;
5007 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5008 ffecom_gfrt_kindtype (gfrt
),
5012 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
5013 ffebld_nonter_hook (expr
));
5014 if (arg3_tree
!= NULL_TREE
)
5015 expr_tree
= ffecom_modify (NULL_TREE
, arg3_tree
,
5016 convert (TREE_TYPE (arg3_tree
),
5021 case FFEINTRIN_impLSTAT_subr
:
5022 case FFEINTRIN_impSTAT_subr
:
5024 tree arg1_len
= integer_zero_node
;
5029 arg1_tree
= ffecom_arg_ptr_to_expr (arg1
, &arg1_len
);
5031 arg2_tree
= ffecom_ptr_to_expr (arg2
);
5034 arg3_tree
= ffecom_expr_w (NULL_TREE
, arg3
);
5036 arg3_tree
= NULL_TREE
;
5038 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
5039 arg1_len
= build_tree_list (NULL_TREE
, arg1_len
);
5040 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
5041 TREE_CHAIN (arg1_tree
) = arg2_tree
;
5042 TREE_CHAIN (arg2_tree
) = arg1_len
;
5043 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5044 ffecom_gfrt_kindtype (gfrt
),
5048 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
5049 ffebld_nonter_hook (expr
));
5050 if (arg3_tree
!= NULL_TREE
)
5051 expr_tree
= ffecom_modify (NULL_TREE
, arg3_tree
,
5052 convert (TREE_TYPE (arg3_tree
),
5057 case FFEINTRIN_impFGETC_subr
:
5058 case FFEINTRIN_impFPUTC_subr
:
5062 tree arg2_len
= integer_zero_node
;
5065 arg1_tree
= convert (ffecom_f2c_integer_type_node
,
5066 ffecom_expr (arg1
));
5067 arg1_tree
= ffecom_1 (ADDR_EXPR
,
5068 build_pointer_type (TREE_TYPE (arg1_tree
)),
5071 arg2_tree
= ffecom_arg_ptr_to_expr (arg2
, &arg2_len
);
5073 arg3_tree
= ffecom_expr_w (NULL_TREE
, arg3
);
5075 arg3_tree
= NULL_TREE
;
5077 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
5078 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
5079 arg2_len
= build_tree_list (NULL_TREE
, arg2_len
);
5080 TREE_CHAIN (arg1_tree
) = arg2_tree
;
5081 TREE_CHAIN (arg2_tree
) = arg2_len
;
5083 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5084 ffecom_gfrt_kindtype (gfrt
),
5088 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
5089 ffebld_nonter_hook (expr
));
5090 if (arg3_tree
!= NULL_TREE
)
5091 expr_tree
= ffecom_modify (NULL_TREE
, arg3_tree
,
5092 convert (TREE_TYPE (arg3_tree
),
5097 case FFEINTRIN_impFSTAT_subr
:
5103 arg1_tree
= convert (ffecom_f2c_integer_type_node
,
5104 ffecom_expr (arg1
));
5105 arg1_tree
= ffecom_1 (ADDR_EXPR
,
5106 build_pointer_type (TREE_TYPE (arg1_tree
)),
5109 arg2_tree
= convert (ffecom_f2c_ptr_to_integer_type_node
,
5110 ffecom_ptr_to_expr (arg2
));
5113 arg3_tree
= NULL_TREE
;
5115 arg3_tree
= ffecom_expr_w (NULL_TREE
, arg3
);
5117 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
5118 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
5119 TREE_CHAIN (arg1_tree
) = arg2_tree
;
5120 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5121 ffecom_gfrt_kindtype (gfrt
),
5125 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
5126 ffebld_nonter_hook (expr
));
5127 if (arg3_tree
!= NULL_TREE
) {
5128 expr_tree
= ffecom_modify (NULL_TREE
, arg3_tree
,
5129 convert (TREE_TYPE (arg3_tree
),
5135 case FFEINTRIN_impKILL_subr
:
5141 arg1_tree
= convert (ffecom_f2c_integer_type_node
,
5142 ffecom_expr (arg1
));
5143 arg1_tree
= ffecom_1 (ADDR_EXPR
,
5144 build_pointer_type (TREE_TYPE (arg1_tree
)),
5147 arg2_tree
= convert (ffecom_f2c_integer_type_node
,
5148 ffecom_expr (arg2
));
5149 arg2_tree
= ffecom_1 (ADDR_EXPR
,
5150 build_pointer_type (TREE_TYPE (arg2_tree
)),
5154 arg3_tree
= NULL_TREE
;
5156 arg3_tree
= ffecom_expr_w (NULL_TREE
, arg3
);
5158 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
5159 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
5160 TREE_CHAIN (arg1_tree
) = arg2_tree
;
5161 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5162 ffecom_gfrt_kindtype (gfrt
),
5166 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
5167 ffebld_nonter_hook (expr
));
5168 if (arg3_tree
!= NULL_TREE
) {
5169 expr_tree
= ffecom_modify (NULL_TREE
, arg3_tree
,
5170 convert (TREE_TYPE (arg3_tree
),
5176 case FFEINTRIN_impCTIME_subr
:
5177 case FFEINTRIN_impTTYNAM_subr
:
5179 tree arg1_len
= integer_zero_node
;
5183 arg1_tree
= ffecom_arg_ptr_to_expr (arg2
, &arg1_len
);
5185 arg2_tree
= convert (((codegen_imp
== FFEINTRIN_impCTIME_subr
) ?
5186 ffecom_f2c_longint_type_node
:
5187 ffecom_f2c_integer_type_node
),
5188 ffecom_expr (arg1
));
5189 arg2_tree
= ffecom_1 (ADDR_EXPR
,
5190 build_pointer_type (TREE_TYPE (arg2_tree
)),
5193 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
5194 arg1_len
= build_tree_list (NULL_TREE
, arg1_len
);
5195 arg2_tree
= build_tree_list (NULL_TREE
, arg2_tree
);
5196 TREE_CHAIN (arg1_len
) = arg2_tree
;
5197 TREE_CHAIN (arg1_tree
) = arg1_len
;
5200 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5201 ffecom_gfrt_kindtype (gfrt
),
5205 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
5206 ffebld_nonter_hook (expr
));
5207 TREE_SIDE_EFFECTS (expr_tree
) = 1;
5211 case FFEINTRIN_impIRAND
:
5212 case FFEINTRIN_impRAND
:
5213 /* Arg defaults to 0 (normal random case) */
5218 arg1_tree
= ffecom_integer_zero_node
;
5220 arg1_tree
= ffecom_expr (arg1
);
5221 arg1_tree
= convert (ffecom_f2c_integer_type_node
,
5223 arg1_tree
= ffecom_1 (ADDR_EXPR
,
5224 build_pointer_type (TREE_TYPE (arg1_tree
)),
5226 arg1_tree
= build_tree_list (NULL_TREE
, arg1_tree
);
5228 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5229 ffecom_gfrt_kindtype (gfrt
),
5231 ((codegen_imp
== FFEINTRIN_impIRAND
) ?
5232 ffecom_f2c_integer_type_node
:
5233 ffecom_f2c_real_type_node
),
5235 dest_tree
, dest
, dest_used
,
5237 ffebld_nonter_hook (expr
));
5241 case FFEINTRIN_impFTELL_subr
:
5242 case FFEINTRIN_impUMASK_subr
:
5247 arg1_tree
= convert (ffecom_f2c_integer_type_node
,
5248 ffecom_expr (arg1
));
5249 arg1_tree
= ffecom_1 (ADDR_EXPR
,
5250 build_pointer_type (TREE_TYPE (arg1_tree
)),
5254 arg2_tree
= NULL_TREE
;
5256 arg2_tree
= ffecom_expr_w (NULL_TREE
, arg2
);
5258 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5259 ffecom_gfrt_kindtype (gfrt
),
5262 build_tree_list (NULL_TREE
, arg1_tree
),
5263 NULL_TREE
, NULL
, NULL
, NULL_TREE
,
5265 ffebld_nonter_hook (expr
));
5266 if (arg2_tree
!= NULL_TREE
) {
5267 expr_tree
= ffecom_modify (NULL_TREE
, arg2_tree
,
5268 convert (TREE_TYPE (arg2_tree
),
5274 case FFEINTRIN_impCPU_TIME
:
5275 case FFEINTRIN_impSECOND_subr
:
5279 arg1_tree
= ffecom_expr_w (NULL_TREE
, arg1
);
5282 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5283 ffecom_gfrt_kindtype (gfrt
),
5287 NULL_TREE
, NULL
, NULL
, NULL_TREE
, TRUE
,
5288 ffebld_nonter_hook (expr
));
5291 = ffecom_modify (NULL_TREE
, arg1_tree
,
5292 convert (TREE_TYPE (arg1_tree
),
5297 case FFEINTRIN_impDTIME_subr
:
5298 case FFEINTRIN_impETIME_subr
:
5303 result_tree
= ffecom_expr_w (NULL_TREE
, arg2
);
5305 arg1_tree
= ffecom_ptr_to_expr (arg1
);
5307 expr_tree
= ffecom_call_ (ffecom_gfrt_tree_ (gfrt
),
5308 ffecom_gfrt_kindtype (gfrt
),
5311 build_tree_list (NULL_TREE
, arg1_tree
),
5312 NULL_TREE
, NULL
, NULL
, NULL_TREE
,
5314 ffebld_nonter_hook (expr
));
5315 expr_tree
= ffecom_modify (NULL_TREE
, result_tree
,
5316 convert (TREE_TYPE (result_tree
),
5321 /* Straightforward calls of libf2c routines: */
5322 case FFEINTRIN_impABORT
:
5323 case FFEINTRIN_impACCESS
:
5324 case FFEINTRIN_impBESJ0
:
5325 case FFEINTRIN_impBESJ1
:
5326 case FFEINTRIN_impBESJN
:
5327 case FFEINTRIN_impBESY0
:
5328 case FFEINTRIN_impBESY1
:
5329 case FFEINTRIN_impBESYN
:
5330 case FFEINTRIN_impCHDIR_func
:
5331 case FFEINTRIN_impCHMOD_func
:
5332 case FFEINTRIN_impDATE
:
5333 case FFEINTRIN_impDATE_AND_TIME
:
5334 case FFEINTRIN_impDBESJ0
:
5335 case FFEINTRIN_impDBESJ1
:
5336 case FFEINTRIN_impDBESJN
:
5337 case FFEINTRIN_impDBESY0
:
5338 case FFEINTRIN_impDBESY1
:
5339 case FFEINTRIN_impDBESYN
:
5340 case FFEINTRIN_impDTIME_func
:
5341 case FFEINTRIN_impETIME_func
:
5342 case FFEINTRIN_impFGETC_func
:
5343 case FFEINTRIN_impFGET_func
:
5344 case FFEINTRIN_impFNUM
:
5345 case FFEINTRIN_impFPUTC_func
:
5346 case FFEINTRIN_impFPUT_func
:
5347 case FFEINTRIN_impFSEEK
:
5348 case FFEINTRIN_impFSTAT_func
:
5349 case FFEINTRIN_impFTELL_func
:
5350 case FFEINTRIN_impGERROR
:
5351 case FFEINTRIN_impGETARG
:
5352 case FFEINTRIN_impGETCWD_func
:
5353 case FFEINTRIN_impGETENV
:
5354 case FFEINTRIN_impGETGID
:
5355 case FFEINTRIN_impGETLOG
:
5356 case FFEINTRIN_impGETPID
:
5357 case FFEINTRIN_impGETUID
:
5358 case FFEINTRIN_impGMTIME
:
5359 case FFEINTRIN_impHOSTNM_func
:
5360 case FFEINTRIN_impIDATE_unix
:
5361 case FFEINTRIN_impIDATE_vxt
:
5362 case FFEINTRIN_impIERRNO
:
5363 case FFEINTRIN_impISATTY
:
5364 case FFEINTRIN_impITIME
:
5365 case FFEINTRIN_impKILL_func
:
5366 case FFEINTRIN_impLINK_func
:
5367 case FFEINTRIN_impLNBLNK
:
5368 case FFEINTRIN_impLSTAT_func
:
5369 case FFEINTRIN_impLTIME
:
5370 case FFEINTRIN_impMCLOCK8
:
5371 case FFEINTRIN_impMCLOCK
:
5372 case FFEINTRIN_impPERROR
:
5373 case FFEINTRIN_impRENAME_func
:
5374 case FFEINTRIN_impSECNDS
:
5375 case FFEINTRIN_impSECOND_func
:
5376 case FFEINTRIN_impSLEEP
:
5377 case FFEINTRIN_impSRAND
:
5378 case FFEINTRIN_impSTAT_func
:
5379 case FFEINTRIN_impSYMLNK_func
:
5380 case FFEINTRIN_impSYSTEM_CLOCK
:
5381 case FFEINTRIN_impSYSTEM_func
:
5382 case FFEINTRIN_impTIME8
:
5383 case FFEINTRIN_impTIME_unix
:
5384 case FFEINTRIN_impTIME_vxt
:
5385 case FFEINTRIN_impUMASK_func
:
5386 case FFEINTRIN_impUNLINK_func
:
5389 case FFEINTRIN_impCTIME_func
: /* CHARACTER functions not handled here. */
5390 case FFEINTRIN_impFDATE_func
: /* CHARACTER functions not handled here. */
5391 case FFEINTRIN_impTTYNAM_func
: /* CHARACTER functions not handled here. */
5392 case FFEINTRIN_impNONE
:
5393 case FFEINTRIN_imp
: /* Hush up gcc warning. */
5394 fprintf (stderr
, "No %s implementation.\n",
5395 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr
))));
5396 assert ("unimplemented intrinsic" == NULL
);
5397 return error_mark_node
;
5400 assert (gfrt
!= FFECOM_gfrt
); /* Must have an implementation! */
5402 expr_tree
= ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt
),
5403 ffebld_right (expr
));
5405 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt
), ffecom_gfrt_kindtype (gfrt
),
5406 (ffe_is_f2c_library () && ffecom_gfrt_complex_
[gfrt
]),
5408 expr_tree
, dest_tree
, dest
, dest_used
,
5410 ffebld_nonter_hook (expr
));
5412 /* See bottom of this file for f2c transforms used to determine
5413 many of the above implementations. The info seems to confuse
5414 Emacs's C mode indentation, which is why it's been moved to
5415 the bottom of this source file. */
5418 /* For power (exponentiation) where right-hand operand is type INTEGER,
5419 generate in-line code to do it the fast way (which, if the operand
5420 is a constant, might just mean a series of multiplies). */
5423 ffecom_expr_power_integer_ (ffebld expr
)
5425 tree l
= ffecom_expr (ffebld_left (expr
));
5426 tree r
= ffecom_expr (ffebld_right (expr
));
5427 tree ltype
= TREE_TYPE (l
);
5428 tree rtype
= TREE_TYPE (r
);
5429 tree result
= NULL_TREE
;
5431 if (l
== error_mark_node
5432 || r
== error_mark_node
)
5433 return error_mark_node
;
5435 if (TREE_CODE (r
) == INTEGER_CST
)
5437 int sgn
= tree_int_cst_sgn (r
);
5440 return convert (ltype
, integer_one_node
);
5442 if ((TREE_CODE (ltype
) == INTEGER_TYPE
)
5445 /* Reciprocal of integer is either 0, -1, or 1, so after
5446 calculating that (which we leave to the back end to do
5447 or not do optimally), don't bother with any multiplying. */
5449 result
= ffecom_tree_divide_ (ltype
,
5450 convert (ltype
, integer_one_node
),
5452 NULL_TREE
, NULL
, NULL
, NULL_TREE
);
5453 r
= ffecom_1 (NEGATE_EXPR
,
5456 if ((TREE_INT_CST_LOW (r
) & 1) == 0)
5457 result
= ffecom_1 (ABS_EXPR
, rtype
,
5461 /* Generate appropriate series of multiplies, preceded
5462 by divide if the exponent is negative. */
5468 l
= ffecom_tree_divide_ (ltype
,
5469 convert (ltype
, integer_one_node
),
5471 NULL_TREE
, NULL
, NULL
,
5472 ffebld_nonter_hook (expr
));
5473 r
= ffecom_1 (NEGATE_EXPR
, rtype
, r
);
5474 assert (TREE_CODE (r
) == INTEGER_CST
);
5476 if (tree_int_cst_sgn (r
) < 0)
5477 { /* The "most negative" number. */
5478 r
= ffecom_1 (NEGATE_EXPR
, rtype
,
5479 ffecom_2 (RSHIFT_EXPR
, rtype
,
5483 l
= ffecom_2 (MULT_EXPR
, ltype
,
5491 if (TREE_INT_CST_LOW (r
) & 1)
5493 if (result
== NULL_TREE
)
5496 result
= ffecom_2 (MULT_EXPR
, ltype
,
5501 r
= ffecom_2 (RSHIFT_EXPR
, rtype
,
5504 if (integer_zerop (r
))
5506 assert (TREE_CODE (r
) == INTEGER_CST
);
5509 l
= ffecom_2 (MULT_EXPR
, ltype
,
5516 /* Though rhs isn't a constant, in-line code cannot be expanded
5517 while transforming dummies
5518 because the back end cannot be easily convinced to generate
5519 stores (MODIFY_EXPR), handle temporaries, and so on before
5520 all the appropriate rtx's have been generated for things like
5521 dummy args referenced in rhs -- which doesn't happen until
5522 store_parm_decls() is called (expand_function_start, I believe,
5523 does the actual rtx-stuffing of PARM_DECLs).
5525 So, in this case, let the caller generate the call to the
5526 run-time-library function to evaluate the power for us. */
5528 if (ffecom_transform_only_dummies_
)
5531 /* Right-hand operand not a constant, expand in-line code to figure
5532 out how to do the multiplies, &c.
5534 The returned expression is expressed this way in GNU C, where l and
5537 ({ typeof (r) rtmp = r;
5538 typeof (l) ltmp = l;
5545 if ((basetypeof (l) == basetypeof (int))
5548 result = ((typeof (l)) 1) / ltmp;
5549 if ((ltmp < 0) && (((-rtmp) & 1) == 0))
5555 if ((basetypeof (l) != basetypeof (int))
5558 ltmp = ((typeof (l)) 1) / ltmp;
5562 rtmp = -(rtmp >> 1);
5570 if ((rtmp >>= 1) == 0)
5579 Note that some of the above is compile-time collapsable, such as
5580 the first part of the if statements that checks the base type of
5581 l against int. The if statements are phrased that way to suggest
5582 an easy way to generate the if/else constructs here, knowing that
5583 the back end should (and probably does) eliminate the resulting
5584 dead code (either the int case or the non-int case), something
5585 it couldn't do without the redundant phrasing, requiring explicit
5586 dead-code elimination here, which would be kind of difficult to
5593 tree basetypeof_l_is_int
;
5598 = build_int_2 ((TREE_CODE (ltype
) == INTEGER_TYPE
), 0);
5600 se
= expand_start_stmt_expr (/*has_scope=*/1);
5602 ffecom_start_compstmt ();
5604 rtmp
= ffecom_make_tempvar ("power_r", rtype
,
5605 FFETARGET_charactersizeNONE
, -1);
5606 ltmp
= ffecom_make_tempvar ("power_l", ltype
,
5607 FFETARGET_charactersizeNONE
, -1);
5608 result
= ffecom_make_tempvar ("power_res", ltype
,
5609 FFETARGET_charactersizeNONE
, -1);
5610 if (TREE_CODE (ltype
) == COMPLEX_TYPE
5611 || TREE_CODE (ltype
) == RECORD_TYPE
)
5612 divide
= ffecom_make_tempvar ("power_div", ltype
,
5613 FFETARGET_charactersizeNONE
, -1);
5617 expand_expr_stmt (ffecom_modify (void_type_node
,
5620 expand_expr_stmt (ffecom_modify (void_type_node
,
5623 expand_start_cond (ffecom_truth_value
5624 (ffecom_2 (EQ_EXPR
, integer_type_node
,
5626 convert (rtype
, integer_zero_node
))),
5628 expand_expr_stmt (ffecom_modify (void_type_node
,
5630 convert (ltype
, integer_one_node
)));
5631 expand_start_else ();
5632 if (! integer_zerop (basetypeof_l_is_int
))
5634 expand_start_cond (ffecom_2 (LT_EXPR
, integer_type_node
,
5637 integer_zero_node
)),
5639 expand_expr_stmt (ffecom_modify (void_type_node
,
5643 convert (ltype
, integer_one_node
),
5645 NULL_TREE
, NULL
, NULL
,
5647 expand_start_cond (ffecom_truth_value
5648 (ffecom_2 (TRUTH_ANDIF_EXPR
, integer_type_node
,
5649 ffecom_2 (LT_EXPR
, integer_type_node
,
5652 integer_zero_node
)),
5653 ffecom_2 (EQ_EXPR
, integer_type_node
,
5654 ffecom_2 (BIT_AND_EXPR
,
5656 ffecom_1 (NEGATE_EXPR
,
5662 integer_zero_node
)))),
5664 expand_expr_stmt (ffecom_modify (void_type_node
,
5666 ffecom_1 (NEGATE_EXPR
,
5670 expand_start_else ();
5672 expand_expr_stmt (ffecom_modify (void_type_node
,
5674 convert (ltype
, integer_one_node
)));
5675 expand_start_cond (ffecom_truth_value
5676 (ffecom_2 (TRUTH_ANDIF_EXPR
, integer_type_node
,
5677 ffecom_truth_value_invert
5678 (basetypeof_l_is_int
),
5679 ffecom_2 (LT_EXPR
, integer_type_node
,
5682 integer_zero_node
)))),
5684 expand_expr_stmt (ffecom_modify (void_type_node
,
5688 convert (ltype
, integer_one_node
),
5690 NULL_TREE
, NULL
, NULL
,
5692 expand_expr_stmt (ffecom_modify (void_type_node
,
5694 ffecom_1 (NEGATE_EXPR
, rtype
,
5696 expand_start_cond (ffecom_truth_value
5697 (ffecom_2 (LT_EXPR
, integer_type_node
,
5699 convert (rtype
, integer_zero_node
))),
5701 expand_expr_stmt (ffecom_modify (void_type_node
,
5703 ffecom_1 (NEGATE_EXPR
, rtype
,
5704 ffecom_2 (RSHIFT_EXPR
,
5707 integer_one_node
))));
5708 expand_expr_stmt (ffecom_modify (void_type_node
,
5710 ffecom_2 (MULT_EXPR
, ltype
,
5715 expand_start_loop (1);
5716 expand_start_cond (ffecom_truth_value
5717 (ffecom_2 (BIT_AND_EXPR
, rtype
,
5719 convert (rtype
, integer_one_node
))),
5721 expand_expr_stmt (ffecom_modify (void_type_node
,
5723 ffecom_2 (MULT_EXPR
, ltype
,
5727 expand_exit_loop_if_false (NULL
,
5729 (ffecom_modify (rtype
,
5731 ffecom_2 (RSHIFT_EXPR
,
5734 integer_one_node
))));
5735 expand_expr_stmt (ffecom_modify (void_type_node
,
5737 ffecom_2 (MULT_EXPR
, ltype
,
5742 if (!integer_zerop (basetypeof_l_is_int
))
5744 expand_expr_stmt (result
);
5746 t
= ffecom_end_compstmt ();
5748 result
= expand_end_stmt_expr (se
);
5750 /* This code comes from c-parse.in, after its expand_end_stmt_expr. */
5752 if (TREE_CODE (t
) == BLOCK
)
5754 /* Make a BIND_EXPR for the BLOCK already made. */
5755 result
= build (BIND_EXPR
, TREE_TYPE (result
),
5756 NULL_TREE
, result
, t
);
5757 /* Remove the block from the tree at this point.
5758 It gets put back at the proper place
5759 when the BIND_EXPR is expanded. */
5769 /* ffecom_expr_transform_ -- Transform symbols in expr
5771 ffebld expr; // FFE expression.
5772 ffecom_expr_transform_ (expr);
5774 Recursive descent on expr while transforming any untransformed SYMTERs. */
5777 ffecom_expr_transform_ (ffebld expr
)
5787 switch (ffebld_op (expr
))
5789 case FFEBLD_opSYMTER
:
5790 s
= ffebld_symter (expr
);
5791 t
= ffesymbol_hook (s
).decl_tree
;
5792 if ((t
== NULL_TREE
)
5793 && ((ffesymbol_kind (s
) != FFEINFO_kindNONE
)
5794 || ((ffesymbol_where (s
) != FFEINFO_whereNONE
)
5795 && (ffesymbol_where (s
) != FFEINFO_whereINTRINSIC
))))
5797 s
= ffecom_sym_transform_ (s
);
5798 t
= ffesymbol_hook (s
).decl_tree
; /* Sfunc expr non-dummy,
5801 break; /* Ok if (t == NULL) here. */
5804 ffecom_expr_transform_ (ffebld_head (expr
));
5805 expr
= ffebld_trail (expr
);
5806 goto tail_recurse
; /* :::::::::::::::::::: */
5812 switch (ffebld_arity (expr
))
5815 ffecom_expr_transform_ (ffebld_left (expr
));
5816 expr
= ffebld_right (expr
);
5817 goto tail_recurse
; /* :::::::::::::::::::: */
5820 expr
= ffebld_left (expr
);
5821 goto tail_recurse
; /* :::::::::::::::::::: */
5830 /* Make a type based on info in live f2c.h file. */
5833 ffecom_f2c_make_type_ (tree
*type
, int tcode
, const char *name
)
5837 case FFECOM_f2ccodeCHAR
:
5838 *type
= make_signed_type (CHAR_TYPE_SIZE
);
5841 case FFECOM_f2ccodeSHORT
:
5842 *type
= make_signed_type (SHORT_TYPE_SIZE
);
5845 case FFECOM_f2ccodeINT
:
5846 *type
= make_signed_type (INT_TYPE_SIZE
);
5849 case FFECOM_f2ccodeLONG
:
5850 *type
= make_signed_type (LONG_TYPE_SIZE
);
5853 case FFECOM_f2ccodeLONGLONG
:
5854 *type
= make_signed_type (LONG_LONG_TYPE_SIZE
);
5857 case FFECOM_f2ccodeCHARPTR
:
5858 *type
= build_pointer_type (DEFAULT_SIGNED_CHAR
5859 ? signed_char_type_node
5860 : unsigned_char_type_node
);
5863 case FFECOM_f2ccodeFLOAT
:
5864 *type
= make_node (REAL_TYPE
);
5865 TYPE_PRECISION (*type
) = FLOAT_TYPE_SIZE
;
5866 layout_type (*type
);
5869 case FFECOM_f2ccodeDOUBLE
:
5870 *type
= make_node (REAL_TYPE
);
5871 TYPE_PRECISION (*type
) = DOUBLE_TYPE_SIZE
;
5872 layout_type (*type
);
5875 case FFECOM_f2ccodeLONGDOUBLE
:
5876 *type
= make_node (REAL_TYPE
);
5877 TYPE_PRECISION (*type
) = LONG_DOUBLE_TYPE_SIZE
;
5878 layout_type (*type
);
5881 case FFECOM_f2ccodeTWOREALS
:
5882 *type
= ffecom_make_complex_type_ (ffecom_f2c_real_type_node
);
5885 case FFECOM_f2ccodeTWODOUBLEREALS
:
5886 *type
= ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node
);
5890 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL
);
5891 *type
= error_mark_node
;
5895 pushdecl (build_decl (TYPE_DECL
,
5896 ffecom_get_invented_identifier ("__g77_f2c_%s", name
),
5900 /* Set the f2c list-directed-I/O code for whatever (integral) type has the
5904 ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt
, int size
,
5910 for (j
= 0; ((size_t) j
) < ARRAY_SIZE (ffecom_tree_type
[0]); ++j
)
5911 if ((t
= ffecom_tree_type
[bt
][j
]) != NULL_TREE
5912 && compare_tree_int (TYPE_SIZE (t
), size
) == 0)
5914 assert (code
!= -1);
5915 ffecom_f2c_typecode_
[bt
][j
] = code
;
5920 /* Finish up globals after doing all program units in file
5922 Need to handle only uninitialized COMMON areas. */
5925 ffecom_finish_global_ (ffeglobal global
)
5931 if (ffeglobal_type (global
) != FFEGLOBAL_typeCOMMON
)
5934 if (ffeglobal_common_init (global
))
5937 cbt
= ffeglobal_hook (global
);
5938 if ((cbt
== NULL_TREE
)
5939 || !ffeglobal_common_have_size (global
))
5940 return global
; /* No need to make common, never ref'd. */
5942 DECL_EXTERNAL (cbt
) = 0;
5944 /* Give the array a size now. */
5946 size
= build_int_2 ((ffeglobal_common_size (global
)
5947 + ffeglobal_common_pad (global
)) - 1,
5950 cbtype
= TREE_TYPE (cbt
);
5951 TYPE_DOMAIN (cbtype
) = build_range_type (integer_type_node
,
5954 if (!TREE_TYPE (size
))
5955 TREE_TYPE (size
) = TYPE_DOMAIN (cbtype
);
5956 layout_type (cbtype
);
5958 cbt
= start_decl (cbt
, FALSE
);
5959 assert (cbt
== ffeglobal_hook (global
));
5961 finish_decl (cbt
, NULL_TREE
, FALSE
);
5966 /* Finish up any untransformed symbols. */
5969 ffecom_finish_symbol_transform_ (ffesymbol s
)
5971 if ((s
== NULL
) || (TREE_CODE (current_function_decl
) == ERROR_MARK
))
5974 /* It's easy to know to transform an untransformed symbol, to make sure
5975 we put out debugging info for it. But COMMON variables, unlike
5976 EQUIVALENCE ones, aren't given declarations in addition to the
5977 tree expressions that specify offsets, because COMMON variables
5978 can be referenced in the outer scope where only dummy arguments
5979 (PARM_DECLs) should really be seen. To be safe, just don't do any
5980 VAR_DECLs for COMMON variables when we transform them for real
5981 use, and therefore we do all the VAR_DECL creating here. */
5983 if (ffesymbol_hook (s
).decl_tree
== NULL_TREE
)
5985 if (ffesymbol_kind (s
) != FFEINFO_kindNONE
5986 || (ffesymbol_where (s
) != FFEINFO_whereNONE
5987 && ffesymbol_where (s
) != FFEINFO_whereINTRINSIC
5988 && ffesymbol_where (s
) != FFEINFO_whereDUMMY
))
5989 /* Not transformed, and not CHARACTER*(*), and not a dummy
5990 argument, which can happen only if the entry point names
5991 it "rides in on" are all invalidated for other reasons. */
5992 s
= ffecom_sym_transform_ (s
);
5995 if ((ffesymbol_where (s
) == FFEINFO_whereCOMMON
)
5996 && (ffesymbol_hook (s
).decl_tree
!= error_mark_node
))
5998 /* This isn't working, at least for dbxout. The .s file looks
5999 okay to me (burley), but in gdb 4.9 at least, the variables
6000 appear to reside somewhere outside of the common area, so
6001 it doesn't make sense to mislead anyone by generating the info
6002 on those variables until this is fixed. NOTE: Same problem
6003 with EQUIVALENCE, sadly...see similar #if later. */
6004 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s
)),
6005 ffesymbol_storage (s
));
6011 /* Append underscore(s) to name before calling get_identifier. "us"
6012 is nonzero if the name already contains an underscore and thus
6013 needs two underscores appended. */
6016 ffecom_get_appended_identifier_ (char us
, const char *name
)
6022 newname
= xmalloc ((i
= strlen (name
)) + 1
6023 + ffe_is_underscoring ()
6025 memcpy (newname
, name
, i
);
6027 newname
[i
+ us
] = '_';
6028 newname
[i
+ 1 + us
] = '\0';
6029 id
= get_identifier (newname
);
6036 /* Decide whether to append underscore to name before calling
6040 ffecom_get_external_identifier_ (ffesymbol s
)
6043 const char *name
= ffesymbol_text (s
);
6045 /* If name is a built-in name, just return it as is. */
6047 if (!ffe_is_underscoring ()
6048 || (strcmp (name
, FFETARGET_nameBLANK_COMMON
) == 0)
6049 || (strcmp (name
, FFETARGET_nameUNNAMED_MAIN
) == 0)
6050 || (strcmp (name
, FFETARGET_nameUNNAMED_BLOCK_DATA
) == 0))
6051 return get_identifier (name
);
6053 us
= ffe_is_second_underscore ()
6054 ? (strchr (name
, '_') != NULL
)
6057 return ffecom_get_appended_identifier_ (us
, name
);
6060 /* Decide whether to append underscore to internal name before calling
6063 This is for non-external, top-function-context names only. Transform
6064 identifier so it doesn't conflict with the transformed result
6065 of using a _different_ external name. E.g. if "CALL FOO" is
6066 transformed into "FOO_();", then the variable in "FOO_ = 3"
6067 must be transformed into something that does not conflict, since
6068 these two things should be independent.
6070 The transformation is as follows. If the name does not contain
6071 an underscore, there is no possible conflict, so just return.
6072 If the name does contain an underscore, then transform it just
6073 like we transform an external identifier. */
6076 ffecom_get_identifier_ (const char *name
)
6078 /* If name does not contain an underscore, just return it as is. */
6080 if (!ffe_is_underscoring ()
6081 || (strchr (name
, '_') == NULL
))
6082 return get_identifier (name
);
6084 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
6088 /* ffecom_gen_sfuncdef_ -- Generate definition of statement function
6091 ffesymbol s; // kindFUNCTION, whereIMMEDIATE.
6092 t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s),
6093 ffesymbol_kindtype(s));
6095 Call after setting up containing function and getting trees for all
6099 ffecom_gen_sfuncdef_ (ffesymbol s
, ffeinfoBasictype bt
, ffeinfoKindtype kt
)
6101 ffebld expr
= ffesymbol_sfexpr (s
);
6105 bool charfunc
= (bt
== FFEINFO_basictypeCHARACTER
);
6106 static bool recurse
= FALSE
;
6107 location_t old_loc
= input_location
;
6109 ffecom_nested_entry_
= s
;
6111 /* For now, we don't have a handy pointer to where the sfunc is actually
6112 defined, though that should be easy to add to an ffesymbol. (The
6113 token/where info available might well point to the place where the type
6114 of the sfunc is declared, especially if that precedes the place where
6115 the sfunc itself is defined, which is typically the case.) We should
6116 put out a null pointer rather than point somewhere wrong, but I want to
6117 see how it works at this point. */
6119 input_filename
= ffesymbol_where_filename (s
);
6120 input_line
= ffesymbol_where_filelinenum (s
);
6122 /* Pretransform the expression so any newly discovered things belong to the
6123 outer program unit, not to the statement function. */
6125 ffecom_expr_transform_ (expr
);
6127 /* Make sure no recursive invocation of this fn (a specific case of failing
6128 to pretransform an sfunc's expression, i.e. where its expression
6129 references another untransformed sfunc) happens. */
6134 push_f_function_context ();
6137 type
= void_type_node
;
6140 type
= ffecom_tree_type
[bt
][kt
];
6141 if (type
== NULL_TREE
)
6142 type
= integer_type_node
; /* _sym_exec_transition reports
6146 start_function (ffecom_get_identifier_ (ffesymbol_text (s
)),
6147 build_function_type (type
, NULL_TREE
),
6148 1, /* nested/inline */
6149 0); /* TREE_PUBLIC */
6151 /* We don't worry about COMPLEX return values here, because this is
6152 entirely internal to our code, and gcc has the ability to return COMPLEX
6153 directly as a value. */
6156 { /* Prepend arg for where result goes. */
6159 type
= ffecom_tree_type
[FFEINFO_basictypeCHARACTER
][kt
];
6161 result
= ffecom_get_invented_identifier ("__g77_%s", "result");
6163 ffecom_char_enhance_arg_ (&type
, s
); /* Ignore returned length. */
6165 type
= build_pointer_type (type
);
6166 result
= build_decl (PARM_DECL
, result
, type
);
6168 push_parm_decl (result
);
6171 result
= NULL_TREE
; /* Not ref'd if !charfunc. */
6173 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s
), TRUE
);
6175 store_parm_decls (0);
6177 ffecom_start_compstmt ();
6183 ffetargetCharacterSize sz
= ffesymbol_size (s
);
6186 result_length
= build_int_2 (sz
, 0);
6187 TREE_TYPE (result_length
) = ffecom_f2c_ftnlen_type_node
;
6189 ffecom_prepare_let_char_ (sz
, expr
);
6191 ffecom_prepare_end ();
6193 ffecom_let_char_ (result
, result_length
, sz
, expr
);
6194 expand_null_return ();
6198 ffecom_prepare_expr (expr
);
6200 ffecom_prepare_end ();
6202 expand_return (ffecom_modify (NULL_TREE
,
6203 DECL_RESULT (current_function_decl
),
6204 ffecom_expr (expr
)));
6208 ffecom_end_compstmt ();
6210 func
= current_function_decl
;
6211 finish_function (1);
6213 pop_f_function_context ();
6217 input_location
= old_loc
;
6219 ffecom_nested_entry_
= NULL
;
6225 ffecom_gfrt_args_ (ffecomGfrt ix
)
6227 return ffecom_gfrt_argstring_
[ix
];
6231 ffecom_gfrt_tree_ (ffecomGfrt ix
)
6233 if (ffecom_gfrt_
[ix
] == NULL_TREE
)
6234 ffecom_make_gfrt_ (ix
);
6236 return ffecom_1 (ADDR_EXPR
,
6237 build_pointer_type (TREE_TYPE (ffecom_gfrt_
[ix
])),
6241 /* Return initialize-to-zero expression for this VAR_DECL. */
6243 /* A somewhat evil way to prevent the garbage collector
6244 from collecting 'tree' structures. */
6245 #define NUM_TRACKED_CHUNK 63
6246 struct tree_ggc_tracker
GTY(())
6248 struct tree_ggc_tracker
*next
;
6249 tree trees
[NUM_TRACKED_CHUNK
];
6251 static GTY(()) struct tree_ggc_tracker
*tracker_head
;
6254 ffecom_save_tree_forever (tree t
)
6257 if (tracker_head
!= NULL
)
6258 for (i
= 0; i
< NUM_TRACKED_CHUNK
; i
++)
6259 if (tracker_head
->trees
[i
] == NULL
)
6261 tracker_head
->trees
[i
] = t
;
6266 /* Need to allocate a new block. */
6267 struct tree_ggc_tracker
*old_head
= tracker_head
;
6269 tracker_head
= ggc_alloc (sizeof (*tracker_head
));
6270 tracker_head
->next
= old_head
;
6271 tracker_head
->trees
[0] = t
;
6272 for (i
= 1; i
< NUM_TRACKED_CHUNK
; i
++)
6273 tracker_head
->trees
[i
] = NULL
;
6278 ffecom_init_zero_ (tree decl
)
6281 int incremental
= TREE_STATIC (decl
);
6282 tree type
= TREE_TYPE (decl
);
6286 make_decl_rtl (decl
, NULL
);
6287 assemble_variable (decl
, TREE_PUBLIC (decl
) ? 1 : 0, 0, 1);
6290 if ((TREE_CODE (type
) != ARRAY_TYPE
)
6291 && (TREE_CODE (type
) != RECORD_TYPE
)
6292 && (TREE_CODE (type
) != UNION_TYPE
)
6294 init
= convert (type
, integer_zero_node
);
6295 else if (!incremental
)
6297 init
= build_constructor (type
, NULL_TREE
);
6298 TREE_CONSTANT (init
) = 1;
6299 TREE_STATIC (init
) = 1;
6303 assemble_zeros (int_size_in_bytes (type
));
6304 init
= error_mark_node
;
6311 ffecom_intrinsic_ichar_ (tree tree_type
, ffebld arg
,
6317 switch (ffebld_op (arg
))
6319 case FFEBLD_opCONTER
: /* For F90, check 0-length. */
6320 if (ffetarget_length_character1
6321 (ffebld_constant_character1
6322 (ffebld_conter (arg
))) == 0)
6324 *maybe_tree
= integer_zero_node
;
6325 return convert (tree_type
, integer_zero_node
);
6328 *maybe_tree
= integer_one_node
;
6329 expr_tree
= build_int_2 (*ffetarget_text_character1
6330 (ffebld_constant_character1
6331 (ffebld_conter (arg
))),
6333 TREE_TYPE (expr_tree
) = tree_type
;
6336 case FFEBLD_opSYMTER
:
6337 case FFEBLD_opARRAYREF
:
6338 case FFEBLD_opFUNCREF
:
6339 case FFEBLD_opSUBSTR
:
6340 ffecom_char_args_ (&expr_tree
, &length_tree
, arg
);
6342 if ((expr_tree
== error_mark_node
)
6343 || (length_tree
== error_mark_node
))
6345 *maybe_tree
= error_mark_node
;
6346 return error_mark_node
;
6349 if (integer_zerop (length_tree
))
6351 *maybe_tree
= integer_zero_node
;
6352 return convert (tree_type
, integer_zero_node
);
6356 = ffecom_1 (INDIRECT_REF
,
6357 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree
))),
6360 = ffecom_2 (ARRAY_REF
,
6361 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree
))),
6364 expr_tree
= convert (tree_type
, expr_tree
);
6366 if (TREE_CODE (length_tree
) == INTEGER_CST
)
6367 *maybe_tree
= integer_one_node
;
6368 else /* Must check length at run time. */
6370 = ffecom_truth_value
6371 (ffecom_2 (GT_EXPR
, integer_type_node
,
6373 ffecom_f2c_ftnlen_zero_node
));
6376 case FFEBLD_opPAREN
:
6377 case FFEBLD_opCONVERT
:
6378 if (ffeinfo_size (ffebld_info (arg
)) == 0)
6380 *maybe_tree
= integer_zero_node
;
6381 return convert (tree_type
, integer_zero_node
);
6383 return ffecom_intrinsic_ichar_ (tree_type
, ffebld_left (arg
),
6386 case FFEBLD_opCONCATENATE
:
6393 expr_left
= ffecom_intrinsic_ichar_ (tree_type
, ffebld_left (arg
),
6395 expr_right
= ffecom_intrinsic_ichar_ (tree_type
, ffebld_right (arg
),
6397 *maybe_tree
= ffecom_2 (TRUTH_ORIF_EXPR
, integer_type_node
,
6400 expr_tree
= ffecom_3 (COND_EXPR
, tree_type
,
6408 assert ("bad op in ICHAR" == NULL
);
6409 return error_mark_node
;
6413 /* ffecom_intrinsic_len_ -- Return length info for char arg (LEN())
6417 length_arg = ffecom_intrinsic_len_ (expr);
6419 Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF
6420 subexpressions by constructing the appropriate tree for the
6421 length-of-character-text argument in a calling sequence. */
6424 ffecom_intrinsic_len_ (ffebld expr
)
6426 ffetargetCharacter1 val
;
6429 switch (ffebld_op (expr
))
6431 case FFEBLD_opCONTER
:
6432 val
= ffebld_constant_character1 (ffebld_conter (expr
));
6433 length
= build_int_2 (ffetarget_length_character1 (val
), 0);
6434 TREE_TYPE (length
) = ffecom_f2c_ftnlen_type_node
;
6437 case FFEBLD_opSYMTER
:
6439 ffesymbol s
= ffebld_symter (expr
);
6442 item
= ffesymbol_hook (s
).decl_tree
;
6443 if (item
== NULL_TREE
)
6445 s
= ffecom_sym_transform_ (s
);
6446 item
= ffesymbol_hook (s
).decl_tree
;
6448 if (ffesymbol_kind (s
) == FFEINFO_kindENTITY
)
6450 if (ffesymbol_size (s
) == FFETARGET_charactersizeNONE
)
6451 length
= ffesymbol_hook (s
).length_tree
;
6454 length
= build_int_2 (ffesymbol_size (s
), 0);
6455 TREE_TYPE (length
) = ffecom_f2c_ftnlen_type_node
;
6458 else if (item
== error_mark_node
)
6459 length
= error_mark_node
;
6460 else /* FFEINFO_kindFUNCTION: */
6465 case FFEBLD_opARRAYREF
:
6466 length
= ffecom_intrinsic_len_ (ffebld_left (expr
));
6469 case FFEBLD_opSUBSTR
:
6473 ffebld thing
= ffebld_right (expr
);
6477 assert (ffebld_op (thing
) == FFEBLD_opITEM
);
6478 start
= ffebld_head (thing
);
6479 thing
= ffebld_trail (thing
);
6480 assert (ffebld_trail (thing
) == NULL
);
6481 end
= ffebld_head (thing
);
6483 length
= ffecom_intrinsic_len_ (ffebld_left (expr
));
6485 if (length
== error_mark_node
)
6494 length
= convert (ffecom_f2c_ftnlen_type_node
,
6500 start_tree
= convert (ffecom_f2c_ftnlen_type_node
,
6501 ffecom_expr (start
));
6503 if (start_tree
== error_mark_node
)
6505 length
= error_mark_node
;
6511 length
= ffecom_2 (PLUS_EXPR
, ffecom_f2c_ftnlen_type_node
,
6512 ffecom_f2c_ftnlen_one_node
,
6513 ffecom_2 (MINUS_EXPR
,
6514 ffecom_f2c_ftnlen_type_node
,
6520 end_tree
= convert (ffecom_f2c_ftnlen_type_node
,
6523 if (end_tree
== error_mark_node
)
6525 length
= error_mark_node
;
6529 length
= ffecom_2 (PLUS_EXPR
, ffecom_f2c_ftnlen_type_node
,
6530 ffecom_f2c_ftnlen_one_node
,
6531 ffecom_2 (MINUS_EXPR
,
6532 ffecom_f2c_ftnlen_type_node
,
6533 end_tree
, start_tree
));
6539 case FFEBLD_opCONCATENATE
:
6541 = ffecom_2 (PLUS_EXPR
, ffecom_f2c_ftnlen_type_node
,
6542 ffecom_intrinsic_len_ (ffebld_left (expr
)),
6543 ffecom_intrinsic_len_ (ffebld_right (expr
)));
6546 case FFEBLD_opFUNCREF
:
6547 case FFEBLD_opCONVERT
:
6548 length
= build_int_2 (ffebld_size (expr
), 0);
6549 TREE_TYPE (length
) = ffecom_f2c_ftnlen_type_node
;
6553 assert ("bad op for single char arg expr" == NULL
);
6554 length
= ffecom_f2c_ftnlen_zero_node
;
6558 assert (length
!= NULL_TREE
);
6563 /* Handle CHARACTER assignments.
6565 Generates code to do the assignment. Used by ordinary assignment
6566 statement handler ffecom_let_stmt and by statement-function
6567 handler to generate code for a statement function. */
6570 ffecom_let_char_ (tree dest_tree
, tree dest_length
,
6571 ffetargetCharacterSize dest_size
, ffebld source
)
6573 ffecomConcatList_ catlist
;
6578 if ((dest_tree
== error_mark_node
)
6579 || (dest_length
== error_mark_node
))
6582 assert (dest_tree
!= NULL_TREE
);
6583 assert (dest_length
!= NULL_TREE
);
6585 /* Source might be an opCONVERT, which just means it is a different size
6586 than the destination. Since the underlying implementation here handles
6587 that (directly or via the s_copy or s_cat run-time-library functions),
6588 we don't need the "convenience" of an opCONVERT that tells us to
6589 truncate or blank-pad, particularly since the resulting implementation
6590 would probably be slower than otherwise. */
6592 while (ffebld_op (source
) == FFEBLD_opCONVERT
)
6593 source
= ffebld_left (source
);
6595 catlist
= ffecom_concat_list_new_ (source
, dest_size
);
6596 switch (ffecom_concat_list_count_ (catlist
))
6598 case 0: /* Shouldn't happen, but in case it does... */
6599 ffecom_concat_list_kill_ (catlist
);
6600 source_tree
= null_pointer_node
;
6601 source_length
= ffecom_f2c_ftnlen_zero_node
;
6602 expr_tree
= build_tree_list (NULL_TREE
, dest_tree
);
6603 TREE_CHAIN (expr_tree
) = build_tree_list (NULL_TREE
, source_tree
);
6604 TREE_CHAIN (TREE_CHAIN (expr_tree
))
6605 = build_tree_list (NULL_TREE
, dest_length
);
6606 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree
)))
6607 = build_tree_list (NULL_TREE
, source_length
);
6609 expr_tree
= ffecom_call_gfrt (FFECOM_gfrtCOPY
, expr_tree
, NULL_TREE
);
6610 TREE_SIDE_EFFECTS (expr_tree
) = 1;
6612 expand_expr_stmt (expr_tree
);
6616 case 1: /* The (fairly) easy case. */
6617 ffecom_char_args_ (&source_tree
, &source_length
,
6618 ffecom_concat_list_expr_ (catlist
, 0));
6619 ffecom_concat_list_kill_ (catlist
);
6620 assert (source_tree
!= NULL_TREE
);
6621 assert (source_length
!= NULL_TREE
);
6623 if ((source_tree
== error_mark_node
)
6624 || (source_length
== error_mark_node
))
6630 = ffecom_1 (INDIRECT_REF
,
6631 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6635 = ffecom_2 (ARRAY_REF
,
6636 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6641 = ffecom_1 (INDIRECT_REF
,
6642 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6646 = ffecom_2 (ARRAY_REF
,
6647 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
6652 expr_tree
= ffecom_modify (void_type_node
, dest_tree
, source_tree
);
6654 expand_expr_stmt (expr_tree
);
6659 expr_tree
= build_tree_list (NULL_TREE
, dest_tree
);
6660 TREE_CHAIN (expr_tree
) = build_tree_list (NULL_TREE
, source_tree
);
6661 TREE_CHAIN (TREE_CHAIN (expr_tree
))
6662 = build_tree_list (NULL_TREE
, dest_length
);
6663 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree
)))
6664 = build_tree_list (NULL_TREE
, source_length
);
6666 expr_tree
= ffecom_call_gfrt (FFECOM_gfrtCOPY
, expr_tree
, NULL_TREE
);
6667 TREE_SIDE_EFFECTS (expr_tree
) = 1;
6669 expand_expr_stmt (expr_tree
);
6673 default: /* Must actually concatenate things. */
6677 /* Heavy-duty concatenation. */
6680 int count
= ffecom_concat_list_count_ (catlist
);
6692 hook
= ffebld_nonter_hook (source
);
6694 assert (TREE_CODE (hook
) == TREE_VEC
);
6695 assert (TREE_VEC_LENGTH (hook
) == 2);
6696 length_array
= lengths
= TREE_VEC_ELT (hook
, 0);
6697 item_array
= items
= TREE_VEC_ELT (hook
, 1);
6700 for (i
= 0; i
< count
; ++i
)
6702 ffecom_char_args_ (&citem
, &clength
,
6703 ffecom_concat_list_expr_ (catlist
, i
));
6704 if ((citem
== error_mark_node
)
6705 || (clength
== error_mark_node
))
6707 ffecom_concat_list_kill_ (catlist
);
6712 = ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (items
),
6713 ffecom_modify (void_type_node
,
6714 ffecom_2 (ARRAY_REF
,
6715 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array
))),
6717 build_int_2 (i
, 0)),
6721 = ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (lengths
),
6722 ffecom_modify (void_type_node
,
6723 ffecom_2 (ARRAY_REF
,
6724 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array
))),
6726 build_int_2 (i
, 0)),
6731 expr_tree
= build_tree_list (NULL_TREE
, dest_tree
);
6732 TREE_CHAIN (expr_tree
)
6733 = build_tree_list (NULL_TREE
,
6734 ffecom_1 (ADDR_EXPR
,
6735 build_pointer_type (TREE_TYPE (items
)),
6737 TREE_CHAIN (TREE_CHAIN (expr_tree
))
6738 = build_tree_list (NULL_TREE
,
6739 ffecom_1 (ADDR_EXPR
,
6740 build_pointer_type (TREE_TYPE (lengths
)),
6742 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree
)))
6745 ffecom_1 (ADDR_EXPR
, ffecom_f2c_ptr_to_ftnlen_type_node
,
6746 convert (ffecom_f2c_ftnlen_type_node
,
6747 build_int_2 (count
, 0))));
6748 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree
))))
6749 = build_tree_list (NULL_TREE
, dest_length
);
6751 expr_tree
= ffecom_call_gfrt (FFECOM_gfrtCAT
, expr_tree
, NULL_TREE
);
6752 TREE_SIDE_EFFECTS (expr_tree
) = 1;
6754 expand_expr_stmt (expr_tree
);
6757 ffecom_concat_list_kill_ (catlist
);
6760 /* ffecom_make_gfrt_ -- Make initial info for run-time routine
6763 ffecom_make_gfrt_(ix);
6765 Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL
6766 for the indicated run-time routine (ix). */
6769 ffecom_make_gfrt_ (ffecomGfrt ix
)
6774 switch (ffecom_gfrt_type_
[ix
])
6776 case FFECOM_rttypeVOID_
:
6777 ttype
= void_type_node
;
6780 case FFECOM_rttypeVOIDSTAR_
:
6781 ttype
= TREE_TYPE (null_pointer_node
); /* `void *'. */
6784 case FFECOM_rttypeFTNINT_
:
6785 ttype
= ffecom_f2c_ftnint_type_node
;
6788 case FFECOM_rttypeINTEGER_
:
6789 ttype
= ffecom_f2c_integer_type_node
;
6792 case FFECOM_rttypeLONGINT_
:
6793 ttype
= ffecom_f2c_longint_type_node
;
6796 case FFECOM_rttypeLOGICAL_
:
6797 ttype
= ffecom_f2c_logical_type_node
;
6800 case FFECOM_rttypeREAL_F2C_
:
6801 ttype
= double_type_node
;
6804 case FFECOM_rttypeREAL_GNU_
:
6805 ttype
= float_type_node
;
6808 case FFECOM_rttypeCOMPLEX_F2C_
:
6809 ttype
= void_type_node
;
6812 case FFECOM_rttypeCOMPLEX_GNU_
:
6813 ttype
= ffecom_f2c_complex_type_node
;
6816 case FFECOM_rttypeDOUBLE_
:
6817 ttype
= double_type_node
;
6820 case FFECOM_rttypeDOUBLEREAL_
:
6821 ttype
= ffecom_f2c_doublereal_type_node
;
6824 case FFECOM_rttypeDBLCMPLX_F2C_
:
6825 ttype
= void_type_node
;
6828 case FFECOM_rttypeDBLCMPLX_GNU_
:
6829 ttype
= ffecom_f2c_doublecomplex_type_node
;
6832 case FFECOM_rttypeCHARACTER_
:
6833 ttype
= void_type_node
;
6838 assert ("bad rttype" == NULL
);
6842 ttype
= build_function_type (ttype
, NULL_TREE
);
6843 t
= build_decl (FUNCTION_DECL
,
6844 get_identifier (ffecom_gfrt_name_
[ix
]),
6846 DECL_EXTERNAL (t
) = 1;
6847 TREE_READONLY (t
) = ffecom_gfrt_const_
[ix
] ? 1 : 0;
6848 TREE_PUBLIC (t
) = 1;
6849 TREE_THIS_VOLATILE (t
) = ffecom_gfrt_volatile_
[ix
] ? 1 : 0;
6851 /* Sanity check: A function that's const cannot be volatile. */
6853 assert (ffecom_gfrt_const_
[ix
] ? !ffecom_gfrt_volatile_
[ix
] : 1);
6855 /* Sanity check: A function that's const cannot return complex. */
6857 assert (ffecom_gfrt_const_
[ix
] ? !ffecom_gfrt_complex_
[ix
] : 1);
6859 t
= start_decl (t
, TRUE
);
6861 finish_decl (t
, NULL_TREE
, TRUE
);
6863 ffecom_gfrt_
[ix
] = t
;
6866 /* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */
6869 ffecom_member_phase1_ (ffestorag mst UNUSED
, ffestorag st
)
6871 ffesymbol s
= ffestorag_symbol (st
);
6873 if (ffesymbol_namelisted (s
))
6874 ffecom_member_namelisted_
= TRUE
;
6877 /* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare
6878 the member so debugger will see it. Otherwise nobody should be
6879 referencing the member. */
6882 ffecom_member_phase2_ (ffestorag mst
, ffestorag st
)
6890 || ((mt
= ffestorag_hook (mst
)) == NULL
)
6891 || (mt
== error_mark_node
))
6895 || ((s
= ffestorag_symbol (st
)) == NULL
))
6898 type
= ffecom_type_localvar_ (s
,
6899 ffesymbol_basictype (s
),
6900 ffesymbol_kindtype (s
));
6901 if (type
== error_mark_node
)
6904 t
= build_decl (VAR_DECL
,
6905 ffecom_get_identifier_ (ffesymbol_text (s
)),
6908 TREE_STATIC (t
) = TREE_STATIC (mt
);
6909 DECL_INITIAL (t
) = NULL_TREE
;
6910 TREE_ASM_WRITTEN (t
) = 1;
6914 gen_rtx (MEM
, TYPE_MODE (type
),
6915 plus_constant (XEXP (DECL_RTL (mt
), 0),
6916 ffestorag_modulo (mst
)
6917 + ffestorag_offset (st
)
6918 - ffestorag_offset (mst
))));
6920 t
= start_decl (t
, FALSE
);
6922 finish_decl (t
, NULL_TREE
, FALSE
);
6925 /* Prepare source expression for assignment into a destination perhaps known
6926 to be of a specific size. */
6929 ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size
, ffebld source
)
6931 ffecomConcatList_ catlist
;
6936 tree tempvar
= NULL_TREE
;
6938 while (ffebld_op (source
) == FFEBLD_opCONVERT
)
6939 source
= ffebld_left (source
);
6941 catlist
= ffecom_concat_list_new_ (source
, dest_size
);
6942 count
= ffecom_concat_list_count_ (catlist
);
6947 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node
,
6948 FFETARGET_charactersizeNONE
, count
);
6950 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node
,
6951 FFETARGET_charactersizeNONE
, count
);
6953 tempvar
= make_tree_vec (2);
6954 TREE_VEC_ELT (tempvar
, 0) = ltmp
;
6955 TREE_VEC_ELT (tempvar
, 1) = itmp
;
6958 for (i
= 0; i
< count
; ++i
)
6959 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist
, i
));
6961 ffecom_concat_list_kill_ (catlist
);
6965 ffebld_nonter_set_hook (source
, tempvar
);
6966 current_binding_level
->prep_state
= 1;
6970 /* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order
6972 Ignores STAR (alternate-return) dummies. All other get exec-transitioned
6973 (which generates their trees) and then their trees get push_parm_decl'd.
6975 The second arg is TRUE if the dummies are for a statement function, in
6976 which case lengths are not pushed for character arguments (since they are
6977 always known by both the caller and the callee, though the code allows
6978 for someday permitting CHAR*(*) stmtfunc dummies). */
6981 ffecom_push_dummy_decls_ (ffebld dummy_list
, bool stmtfunc
)
6988 ffecom_transform_only_dummies_
= TRUE
;
6990 /* First push the parms corresponding to actual dummy "contents". */
6992 for (dumlist
= dummy_list
; dumlist
!= NULL
; dumlist
= ffebld_trail (dumlist
))
6994 dummy
= ffebld_head (dumlist
);
6995 switch (ffebld_op (dummy
))
6999 continue; /* Forget alternate returns. */
7004 assert (ffebld_op (dummy
) == FFEBLD_opSYMTER
);
7005 s
= ffebld_symter (dummy
);
7006 parm
= ffesymbol_hook (s
).decl_tree
;
7007 if (parm
== NULL_TREE
)
7009 s
= ffecom_sym_transform_ (s
);
7010 parm
= ffesymbol_hook (s
).decl_tree
;
7011 assert (parm
!= NULL_TREE
);
7013 if (parm
!= error_mark_node
)
7014 push_parm_decl (parm
);
7017 /* Then, for CHARACTER dummies, push the parms giving their lengths. */
7019 for (dumlist
= dummy_list
; dumlist
!= NULL
; dumlist
= ffebld_trail (dumlist
))
7021 dummy
= ffebld_head (dumlist
);
7022 switch (ffebld_op (dummy
))
7026 continue; /* Forget alternate returns, they mean
7032 s
= ffebld_symter (dummy
);
7033 if (ffesymbol_basictype (s
) != FFEINFO_basictypeCHARACTER
)
7034 continue; /* Only looking for CHARACTER arguments. */
7035 if (stmtfunc
&& (ffesymbol_size (s
) != FFETARGET_charactersizeNONE
))
7036 continue; /* Stmtfunc arg with known size needs no
7038 if (ffesymbol_kind (s
) != FFEINFO_kindENTITY
)
7039 continue; /* Only looking for variables and arrays. */
7040 parm
= ffesymbol_hook (s
).length_tree
;
7041 assert (parm
!= NULL_TREE
);
7042 if (parm
!= error_mark_node
)
7043 push_parm_decl (parm
);
7046 ffecom_transform_only_dummies_
= FALSE
;
7049 /* ffecom_start_progunit_ -- Beginning of program unit
7051 Does GNU back end stuff necessary to teach it about the start of its
7052 equivalent of a Fortran program unit. */
7055 ffecom_start_progunit_ ()
7057 ffesymbol fn
= ffecom_primary_entry_
;
7059 tree id
; /* Identifier (name) of function. */
7060 tree type
; /* Type of function. */
7061 tree result
; /* Result of function. */
7062 ffeinfoBasictype bt
;
7066 ffeglobalType egt
= FFEGLOBAL_type
;
7069 bool altentries
= (ffecom_num_entrypoints_
!= 0);
7072 && (ffecom_primary_entry_kind_
== FFEINFO_kindFUNCTION
)
7073 && (ffecom_master_bt_
== FFEINFO_basictypeNONE
);
7074 bool main_program
= FALSE
;
7075 location_t old_loc
= input_location
;
7077 assert (fn
!= NULL
);
7078 assert (ffesymbol_hook (fn
).decl_tree
== NULL_TREE
);
7080 input_filename
= ffesymbol_where_filename (fn
);
7081 input_line
= ffesymbol_where_filelinenum (fn
);
7083 switch (ffecom_primary_entry_kind_
)
7085 case FFEINFO_kindPROGRAM
:
7086 main_program
= TRUE
;
7087 gt
= FFEGLOBAL_typeMAIN
;
7088 bt
= FFEINFO_basictypeNONE
;
7089 kt
= FFEINFO_kindtypeNONE
;
7090 type
= ffecom_tree_fun_type_void
;
7095 case FFEINFO_kindBLOCKDATA
:
7096 gt
= FFEGLOBAL_typeBDATA
;
7097 bt
= FFEINFO_basictypeNONE
;
7098 kt
= FFEINFO_kindtypeNONE
;
7099 type
= ffecom_tree_fun_type_void
;
7104 case FFEINFO_kindFUNCTION
:
7105 gt
= FFEGLOBAL_typeFUNC
;
7106 egt
= FFEGLOBAL_typeEXT
;
7107 bt
= ffesymbol_basictype (fn
);
7108 kt
= ffesymbol_kindtype (fn
);
7109 if (bt
== FFEINFO_basictypeNONE
)
7111 ffeimplic_establish_symbol (fn
);
7112 if (ffesymbol_funcresult (fn
) != NULL
)
7113 ffeimplic_establish_symbol (ffesymbol_funcresult (fn
));
7114 bt
= ffesymbol_basictype (fn
);
7115 kt
= ffesymbol_kindtype (fn
);
7119 charfunc
= cmplxfunc
= FALSE
;
7120 else if (bt
== FFEINFO_basictypeCHARACTER
)
7121 charfunc
= TRUE
, cmplxfunc
= FALSE
;
7122 else if ((bt
== FFEINFO_basictypeCOMPLEX
)
7123 && ffesymbol_is_f2c (fn
)
7125 charfunc
= FALSE
, cmplxfunc
= TRUE
;
7127 charfunc
= cmplxfunc
= FALSE
;
7129 if (multi
|| charfunc
)
7130 type
= ffecom_tree_fun_type_void
;
7131 else if (ffesymbol_is_f2c (fn
) && !altentries
)
7132 type
= ffecom_tree_fun_type
[bt
][kt
];
7134 type
= build_function_type (ffecom_tree_type
[bt
][kt
], NULL_TREE
);
7136 if ((type
== NULL_TREE
)
7137 || (TREE_TYPE (type
) == NULL_TREE
))
7138 type
= ffecom_tree_fun_type_void
; /* _sym_exec_transition. */
7141 case FFEINFO_kindSUBROUTINE
:
7142 gt
= FFEGLOBAL_typeSUBR
;
7143 egt
= FFEGLOBAL_typeEXT
;
7144 bt
= FFEINFO_basictypeNONE
;
7145 kt
= FFEINFO_kindtypeNONE
;
7146 if (ffecom_is_altreturning_
)
7147 type
= ffecom_tree_subr_type
;
7149 type
= ffecom_tree_fun_type_void
;
7155 assert ("say what??" == NULL
);
7157 case FFEINFO_kindANY
:
7158 gt
= FFEGLOBAL_typeANY
;
7159 bt
= FFEINFO_basictypeNONE
;
7160 kt
= FFEINFO_kindtypeNONE
;
7161 type
= error_mark_node
;
7169 id
= ffecom_get_invented_identifier ("__g77_masterfun_%s",
7170 ffesymbol_text (fn
));
7172 #if FFETARGET_isENFORCED_MAIN
7173 else if (main_program
)
7174 id
= get_identifier (FFETARGET_nameENFORCED_MAIN_NAME
);
7177 id
= ffecom_get_external_identifier_ (fn
);
7181 0, /* nested/inline */
7182 !altentries
); /* TREE_PUBLIC */
7184 TREE_USED (current_function_decl
) = 1; /* Avoid spurious warning if altentries. */
7187 && ((g
= ffesymbol_global (fn
)) != NULL
)
7188 && ((ffeglobal_type (g
) == gt
)
7189 || (ffeglobal_type (g
) == egt
)))
7191 ffeglobal_set_hook (g
, current_function_decl
);
7194 /* Arg handling needs exec-transitioned ffesymbols to work with. But
7195 exec-transitioning needs current_function_decl to be filled in. So we
7196 do these things in two phases. */
7199 { /* 1st arg identifies which entrypoint. */
7200 ffecom_which_entrypoint_decl_
7201 = build_decl (PARM_DECL
,
7202 ffecom_get_invented_identifier ("__g77_%s",
7203 "which_entrypoint"),
7205 push_parm_decl (ffecom_which_entrypoint_decl_
);
7211 { /* Arg for result (return value). */
7216 type
= ffecom_tree_type
[FFEINFO_basictypeCHARACTER
][kt
];
7218 type
= ffecom_tree_type
[FFEINFO_basictypeCOMPLEX
][kt
];
7220 type
= ffecom_multi_type_node_
;
7222 result
= ffecom_get_invented_identifier ("__g77_%s", "result");
7224 /* Make length arg _and_ enhance type info for CHAR arg itself. */
7227 length
= ffecom_char_enhance_arg_ (&type
, fn
);
7229 length
= NULL_TREE
; /* Not ref'd if !charfunc. */
7231 type
= build_pointer_type (type
);
7232 result
= build_decl (PARM_DECL
, result
, type
);
7234 push_parm_decl (result
);
7236 ffecom_multi_retval_
= result
;
7238 ffecom_func_result_
= result
;
7242 push_parm_decl (length
);
7243 ffecom_func_length_
= length
;
7247 if (ffecom_primary_entry_is_proc_
)
7250 arglist
= ffecom_master_arglist_
;
7252 arglist
= ffesymbol_dummyargs (fn
);
7253 ffecom_push_dummy_decls_ (arglist
, FALSE
);
7256 if (TREE_CODE (current_function_decl
) != ERROR_MARK
)
7257 store_parm_decls (main_program
? 1 : 0);
7259 ffecom_start_compstmt ();
7260 /* Disallow temp vars at this level. */
7261 current_binding_level
->prep_state
= 2;
7263 input_location
= old_loc
;
7265 /* This handles any symbols still untransformed, in case -g specified.
7266 This used to be done in ffecom_finish_progunit, but it turns out to
7267 be necessary to do it here so that statement functions are
7268 expanded before code. But don't bother for BLOCK DATA. */
7270 if (ffecom_primary_entry_kind_
!= FFEINFO_kindBLOCKDATA
)
7271 ffesymbol_drive (ffecom_finish_symbol_transform_
);
7274 /* ffecom_sym_transform_ -- Transform FFE sym into backend sym
7277 ffecom_sym_transform_(s);
7279 The ffesymbol_hook info for s is updated with appropriate backend info
7283 ffecom_sym_transform_ (ffesymbol s
)
7285 tree t
; /* Transformed thingy. */
7286 tree tlen
; /* Length if CHAR*(*). */
7287 bool addr
; /* Is t the address of the thingy? */
7288 ffeinfoBasictype bt
;
7291 location_t old_loc
= input_location
;
7293 /* Must ensure special ASSIGN variables are declared at top of outermost
7294 block, else they'll end up in the innermost block when their first
7295 ASSIGN is seen, which leaves them out of scope when they're the
7296 subject of a GOTO or I/O statement.
7298 We make this variable even if -fugly-assign. Just let it go unused,
7299 in case it turns out there are cases where we really want to use this
7300 variable anyway (e.g. ASSIGN to INTEGER*2 variable). */
7302 if (! ffecom_transform_only_dummies_
7303 && ffesymbol_assigned (s
)
7304 && ! ffesymbol_hook (s
).assign_tree
)
7305 s
= ffecom_sym_transform_assign_ (s
);
7307 if (ffesymbol_sfdummyparent (s
) == NULL
)
7309 input_filename
= ffesymbol_where_filename (s
);
7310 input_line
= ffesymbol_where_filelinenum (s
);
7314 ffesymbol sf
= ffesymbol_sfdummyparent (s
);
7316 input_filename
= ffesymbol_where_filename (sf
);
7317 input_line
= ffesymbol_where_filelinenum (sf
);
7320 bt
= ffeinfo_basictype (ffebld_info (s
));
7321 kt
= ffeinfo_kindtype (ffebld_info (s
));
7327 switch (ffesymbol_kind (s
))
7329 case FFEINFO_kindNONE
:
7330 switch (ffesymbol_where (s
))
7332 case FFEINFO_whereDUMMY
: /* Subroutine or function. */
7333 assert (ffecom_transform_only_dummies_
);
7335 /* Before 0.4, this could be ENTITY/DUMMY, but see
7336 ffestu_sym_end_transition -- no longer true (in particular, if
7337 it could be an ENTITY, it _will_ be made one, so that
7338 possibility won't come through here). So we never make length
7339 arg for CHARACTER type. */
7341 t
= build_decl (PARM_DECL
,
7342 ffecom_get_identifier_ (ffesymbol_text (s
)),
7343 ffecom_tree_ptr_to_subr_type
);
7344 DECL_ARTIFICIAL (t
) = 1;
7348 case FFEINFO_whereGLOBAL
: /* Subroutine or function. */
7349 assert (!ffecom_transform_only_dummies_
);
7351 if (((g
= ffesymbol_global (s
)) != NULL
)
7352 && ((ffeglobal_type (g
) == FFEGLOBAL_typeSUBR
)
7353 || (ffeglobal_type (g
) == FFEGLOBAL_typeFUNC
)
7354 || (ffeglobal_type (g
) == FFEGLOBAL_typeEXT
))
7355 && (ffeglobal_hook (g
) != NULL_TREE
)
7356 && ffe_is_globals ())
7358 t
= ffeglobal_hook (g
);
7362 t
= build_decl (FUNCTION_DECL
,
7363 ffecom_get_external_identifier_ (s
),
7364 ffecom_tree_subr_type
); /* Assume subr. */
7365 DECL_EXTERNAL (t
) = 1;
7366 TREE_PUBLIC (t
) = 1;
7368 t
= start_decl (t
, FALSE
);
7369 finish_decl (t
, NULL_TREE
, FALSE
);
7372 && ((ffeglobal_type (g
) == FFEGLOBAL_typeSUBR
)
7373 || (ffeglobal_type (g
) == FFEGLOBAL_typeFUNC
)
7374 || (ffeglobal_type (g
) == FFEGLOBAL_typeEXT
)))
7375 ffeglobal_set_hook (g
, t
);
7377 ffecom_save_tree_forever (t
);
7382 assert ("NONE where unexpected" == NULL
);
7384 case FFEINFO_whereANY
:
7389 case FFEINFO_kindENTITY
:
7390 switch (ffeinfo_where (ffesymbol_info (s
)))
7393 case FFEINFO_whereCONSTANT
:
7394 /* ~~Debugging info needed? */
7395 assert (!ffecom_transform_only_dummies_
);
7396 t
= error_mark_node
; /* Shouldn't ever see this in expr. */
7399 case FFEINFO_whereLOCAL
:
7400 assert (!ffecom_transform_only_dummies_
);
7403 ffestorag st
= ffesymbol_storage (s
);
7406 type
= ffecom_type_localvar_ (s
, bt
, kt
);
7408 if (type
== error_mark_node
)
7410 t
= error_mark_node
;
7415 && (ffestorag_size (st
) == 0))
7417 t
= error_mark_node
;
7422 && (ffestorag_parent (st
) != NULL
))
7423 { /* Child of EQUIVALENCE parent. */
7426 ffetargetOffset offset
;
7428 est
= ffestorag_parent (st
);
7429 ffecom_transform_equiv_ (est
);
7431 et
= ffestorag_hook (est
);
7432 assert (et
!= NULL_TREE
);
7434 if (! TREE_STATIC (et
))
7435 put_var_into_stack (et
, /*rescan=*/true);
7437 offset
= ffestorag_modulo (est
)
7438 + ffestorag_offset (ffesymbol_storage (s
))
7439 - ffestorag_offset (est
);
7441 ffecom_debug_kludge_ (et
, "EQUIVALENCE", s
, type
, offset
);
7443 /* (t_type *) (((char *) &et) + offset) */
7445 t
= convert (string_type_node
, /* (char *) */
7446 ffecom_1 (ADDR_EXPR
,
7447 build_pointer_type (TREE_TYPE (et
)),
7449 t
= ffecom_2 (PLUS_EXPR
, TREE_TYPE (t
),
7451 build_int_2 (offset
, 0));
7452 t
= convert (build_pointer_type (type
),
7454 TREE_CONSTANT (t
) = staticp (et
);
7461 bool init
= ffesymbol_is_init (s
);
7463 t
= build_decl (VAR_DECL
,
7464 ffecom_get_identifier_ (ffesymbol_text (s
)),
7468 || ffesymbol_namelisted (s
)
7469 #ifdef FFECOM_sizeMAXSTACKITEM
7471 && (ffestorag_size (st
) > FFECOM_sizeMAXSTACKITEM
))
7473 || ((ffecom_primary_entry_kind_
!= FFEINFO_kindPROGRAM
)
7474 && (ffecom_primary_entry_kind_
7475 != FFEINFO_kindBLOCKDATA
)
7476 && (ffesymbol_is_save (s
) || ffe_is_saveall ())))
7477 TREE_STATIC (t
) = !ffesymbol_attr (s
, FFESYMBOL_attrADJUSTABLE
);
7479 TREE_STATIC (t
) = 0; /* No need to make static. */
7481 if (init
|| ffe_is_init_local_zero ())
7482 DECL_INITIAL (t
) = error_mark_node
;
7484 /* Keep -Wunused from complaining about var if it
7485 is used as sfunc arg or DATA implied-DO. */
7486 if (ffesymbol_attrs (s
) & FFESYMBOL_attrsSFARG
)
7487 DECL_IN_SYSTEM_HEADER (t
) = 1;
7489 t
= start_decl (t
, FALSE
);
7493 if (ffesymbol_init (s
) != NULL
)
7494 initexpr
= ffecom_expr (ffesymbol_init (s
));
7496 initexpr
= ffecom_init_zero_ (t
);
7498 else if (ffe_is_init_local_zero ())
7499 initexpr
= ffecom_init_zero_ (t
);
7501 initexpr
= NULL_TREE
; /* Not ref'd if !init. */
7503 finish_decl (t
, initexpr
, FALSE
);
7505 if (st
!= NULL
&& DECL_SIZE (t
) != error_mark_node
)
7507 assert (TREE_CODE (DECL_SIZE_UNIT (t
)) == INTEGER_CST
);
7508 assert (0 == compare_tree_int (DECL_SIZE_UNIT (t
),
7509 ffestorag_size (st
)));
7515 case FFEINFO_whereRESULT
:
7516 assert (!ffecom_transform_only_dummies_
);
7518 if (bt
== FFEINFO_basictypeCHARACTER
)
7519 { /* Result is already in list of dummies, use
7521 t
= ffecom_func_result_
;
7522 tlen
= ffecom_func_length_
;
7526 if ((ffecom_num_entrypoints_
== 0)
7527 && (bt
== FFEINFO_basictypeCOMPLEX
)
7528 && (ffesymbol_is_f2c (ffecom_primary_entry_
)))
7529 { /* Result is already in list of dummies, use
7531 t
= ffecom_func_result_
;
7535 if (ffecom_func_result_
!= NULL_TREE
)
7537 t
= ffecom_func_result_
;
7540 if ((ffecom_num_entrypoints_
!= 0)
7541 && (ffecom_master_bt_
== FFEINFO_basictypeNONE
))
7543 assert (ffecom_multi_retval_
!= NULL_TREE
);
7544 t
= ffecom_1 (INDIRECT_REF
, ffecom_multi_type_node_
,
7545 ffecom_multi_retval_
);
7546 t
= ffecom_2 (COMPONENT_REF
, ffecom_tree_type
[bt
][kt
],
7547 t
, ffecom_multi_fields_
[bt
][kt
]);
7552 t
= build_decl (VAR_DECL
,
7553 ffecom_get_identifier_ (ffesymbol_text (s
)),
7554 ffecom_tree_type
[bt
][kt
]);
7555 TREE_STATIC (t
) = 0; /* Put result on stack. */
7556 t
= start_decl (t
, FALSE
);
7557 finish_decl (t
, NULL_TREE
, FALSE
);
7559 ffecom_func_result_
= t
;
7563 case FFEINFO_whereDUMMY
:
7571 bool adjustable
= FALSE
; /* Conditionally adjustable? */
7573 type
= ffecom_tree_type
[bt
][kt
];
7574 if (ffesymbol_sfdummyparent (s
) != NULL
)
7576 if (current_function_decl
== ffecom_outer_function_decl_
)
7577 { /* Exec transition before sfunc
7578 context; get it later. */
7581 t
= ffecom_get_identifier_ (ffesymbol_text
7582 (ffesymbol_sfdummyparent (s
)));
7585 t
= ffecom_get_identifier_ (ffesymbol_text (s
));
7587 assert (ffecom_transform_only_dummies_
);
7589 old_sizes
= get_pending_sizes ();
7590 put_pending_sizes (old_sizes
);
7592 if (bt
== FFEINFO_basictypeCHARACTER
)
7593 tlen
= ffecom_char_enhance_arg_ (&type
, s
);
7594 type
= ffecom_check_size_overflow_ (s
, type
, TRUE
);
7596 for (dl
= ffesymbol_dims (s
); dl
!= NULL
; dl
= ffebld_trail (dl
))
7598 if (type
== error_mark_node
)
7601 dim
= ffebld_head (dl
);
7602 assert (ffebld_op (dim
) == FFEBLD_opBOUNDS
);
7603 if ((ffebld_left (dim
) == NULL
) || ffecom_doing_entry_
)
7604 low
= ffecom_integer_one_node
;
7606 low
= ffecom_expr (ffebld_left (dim
));
7607 assert (ffebld_right (dim
) != NULL
);
7608 if ((ffebld_op (ffebld_right (dim
)) == FFEBLD_opSTAR
)
7609 || ffecom_doing_entry_
)
7611 /* Used to just do high=low. But for ffecom_tree_
7612 canonize_ref_, it probably is important to correctly
7613 assess the size. E.g. given COMPLEX C(*),CFUNC and
7614 C(2)=CFUNC(C), overlap can happen, while it can't
7615 for, say, C(1)=CFUNC(C(2)). */
7616 /* Even more recently used to set to INT_MAX, but that
7617 broke when some overflow checking went into the back
7618 end. Now we just leave the upper bound unspecified. */
7622 high
= ffecom_expr (ffebld_right (dim
));
7624 /* Determine whether array is conditionally adjustable,
7625 to decide whether back-end magic is needed.
7627 Normally the front end uses the back-end function
7628 variable_size to wrap SAVE_EXPR's around expressions
7629 affecting the size/shape of an array so that the
7630 size/shape info doesn't change during execution
7631 of the compiled code even though variables and
7632 functions referenced in those expressions might.
7634 variable_size also makes sure those saved expressions
7635 get evaluated immediately upon entry to the
7636 compiled procedure -- the front end normally doesn't
7637 have to worry about that.
7639 However, there is a problem with this that affects
7640 g77's implementation of entry points, and that is
7641 that it is _not_ true that each invocation of the
7642 compiled procedure is permitted to evaluate
7643 array size/shape info -- because it is possible
7644 that, for some invocations, that info is invalid (in
7645 which case it is "promised" -- i.e. a violation of
7646 the Fortran standard -- that the compiled code
7647 won't reference the array or its size/shape
7648 during that particular invocation).
7650 To phrase this in C terms, consider this gcc function:
7652 void foo (int *n, float (*a)[*n])
7654 // a is "pointer to array ...", fyi.
7657 Suppose that, for some invocations, it is permitted
7658 for a caller of foo to do this:
7662 Now the _written_ code for foo can take such a call
7663 into account by either testing explicitly for whether
7664 (a == NULL) || (n == NULL) -- presumably it is
7665 not permitted to reference *a in various fashions
7666 if (n == NULL) I suppose -- or it can avoid it by
7667 looking at other info (other arguments, static/global
7670 However, this won't work in gcc 2.5.8 because it'll
7671 automatically emit the code to save the "*n"
7672 expression, which'll yield a NULL dereference for
7673 the "foo (NULL, NULL)" call, something the code
7674 for foo cannot prevent.
7676 g77 definitely needs to avoid executing such
7677 code anytime the pointer to the adjustable array
7678 is NULL, because even if its bounds expressions
7679 don't have any references to possible "absent"
7680 variables like "*n" -- say all variable references
7681 are to COMMON variables, i.e. global (though in C,
7682 local static could actually make sense) -- the
7683 expressions could yield other run-time problems
7684 for allowably "dead" values in those variables.
7686 For example, let's consider a more complicated
7692 void foo (float (*a)[i/j])
7697 The above is (essentially) quite valid for Fortran
7698 but, again, for a call like "foo (NULL);", it is
7699 permitted for i and j to be undefined when the
7700 call is made. If j happened to be zero, for
7701 example, emitting the code to evaluate "i/j"
7702 could result in a run-time error.
7704 Offhand, though I don't have my F77 or F90
7705 standards handy, it might even be valid for a
7706 bounds expression to contain a function reference,
7707 in which case I doubt it is permitted for an
7708 implementation to invoke that function in the
7709 Fortran case involved here (invocation of an
7710 alternate ENTRY point that doesn't have the adjustable
7711 array as one of its arguments).
7713 So, the code that the compiler would normally emit
7714 to preevaluate the size/shape info for an
7715 adjustable array _must not_ be executed at run time
7716 in certain cases. Specifically, for Fortran,
7717 the case is when the pointer to the adjustable
7718 array == NULL. (For gnu-ish C, it might be nice
7719 for the source code itself to specify an expression
7720 that, if TRUE, inhibits execution of the code. Or
7721 reverse the sense for elegance.)
7723 (Note that g77 could use a different test than NULL,
7724 actually, since it happens to always pass an
7725 integer to the called function that specifies which
7726 entry point is being invoked. Hmm, this might
7727 solve the next problem.)
7729 One way a user could, I suppose, write "foo" so
7730 it works is to insert COND_EXPR's for the
7731 size/shape info so the dangerous stuff isn't
7732 actually done, as in:
7734 void foo (int *n, float (*a)[(a == NULL) ? 0 : *n])
7739 The next problem is that the front end needs to
7740 be able to tell the back end about the array's
7741 decl _before_ it tells it about the conditional
7742 expression to inhibit evaluation of size/shape info,
7745 To solve this, the front end needs to be able
7746 to give the back end the expression to inhibit
7747 generation of the preevaluation code _after_
7748 it makes the decl for the adjustable array.
7750 Until then, the above example using the COND_EXPR
7751 doesn't pass muster with gcc because the "(a == NULL)"
7752 part has a reference to "a", which is still
7753 undefined at that point.
7755 g77 will therefore use a different mechanism in the
7759 && ((TREE_CODE (low
) != INTEGER_CST
)
7760 || (high
&& TREE_CODE (high
) != INTEGER_CST
)))
7763 #if 0 /* Old approach -- see below. */
7764 if (TREE_CODE (low
) != INTEGER_CST
)
7765 low
= ffecom_3 (COND_EXPR
, integer_type_node
,
7766 ffecom_adjarray_passed_ (s
),
7768 ffecom_integer_zero_node
);
7770 if (high
&& TREE_CODE (high
) != INTEGER_CST
)
7771 high
= ffecom_3 (COND_EXPR
, integer_type_node
,
7772 ffecom_adjarray_passed_ (s
),
7774 ffecom_integer_zero_node
);
7777 /* ~~~gcc/stor-layout.c (layout_type) should do this,
7778 probably. Fixes 950302-1.f. */
7780 if (TREE_CODE (low
) != INTEGER_CST
)
7781 low
= variable_size (low
);
7783 /* ~~~Similarly, this fixes dumb0.f. The C front end
7784 does this, which is why dumb0.c would work. */
7786 if (high
&& TREE_CODE (high
) != INTEGER_CST
)
7787 high
= variable_size (high
);
7792 build_range_type (ffecom_integer_type_node
,
7794 type
= ffecom_check_size_overflow_ (s
, type
, TRUE
);
7797 if (type
== error_mark_node
)
7799 t
= error_mark_node
;
7803 if ((ffesymbol_sfdummyparent (s
) == NULL
)
7804 || (ffesymbol_basictype (s
) == FFEINFO_basictypeCHARACTER
))
7806 type
= build_pointer_type (type
);
7810 t
= build_decl (PARM_DECL
, t
, type
);
7811 DECL_ARTIFICIAL (t
) = 1;
7813 /* If this arg is present in every entry point's list of
7814 dummy args, then we're done. */
7816 if (ffesymbol_numentries (s
)
7817 == (ffecom_num_entrypoints_
+ 1))
7822 /* If variable_size in stor-layout has been called during
7823 the above, then get_pending_sizes should have the
7824 yet-to-be-evaluated saved expressions pending.
7825 Make the whole lot of them get emitted, conditionally
7826 on whether the array decl ("t" above) is not NULL. */
7829 tree sizes
= get_pending_sizes ();
7834 tem
= TREE_CHAIN (tem
))
7836 tree temv
= TREE_VALUE (tem
);
7842 = ffecom_2 (COMPOUND_EXPR
,
7851 = ffecom_3 (COND_EXPR
,
7858 convert (TREE_TYPE (sizes
),
7859 integer_zero_node
));
7860 sizes
= ffecom_save_tree (sizes
);
7863 = tree_cons (NULL_TREE
, sizes
, tem
);
7867 put_pending_sizes (sizes
);
7873 && (ffesymbol_numentries (s
)
7874 != ffecom_num_entrypoints_
+ 1))
7876 = ffecom_2 (NE_EXPR
, integer_type_node
,
7882 && (ffesymbol_numentries (s
)
7883 != ffecom_num_entrypoints_
+ 1))
7885 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED
);
7886 ffebad_here (0, ffesymbol_where_line (s
),
7887 ffesymbol_where_column (s
));
7888 ffebad_string (ffesymbol_text (s
));
7897 case FFEINFO_whereCOMMON
:
7902 ffestorag st
= ffesymbol_storage (s
);
7905 cs
= ffesymbol_common (s
); /* The COMMON area itself. */
7906 if (st
!= NULL
) /* Else not laid out. */
7908 ffecom_transform_common_ (cs
);
7909 st
= ffesymbol_storage (s
);
7912 type
= ffecom_type_localvar_ (s
, bt
, kt
);
7914 cg
= ffesymbol_global (cs
); /* The global COMMON info. */
7916 || (ffeglobal_type (cg
) != FFEGLOBAL_typeCOMMON
))
7919 ct
= ffeglobal_hook (cg
); /* The common area's tree. */
7921 if ((ct
== NULL_TREE
)
7923 || (type
== error_mark_node
))
7924 t
= error_mark_node
;
7927 ffetargetOffset offset
;
7930 cst
= ffestorag_parent (st
);
7931 assert (cst
== ffesymbol_storage (cs
));
7933 offset
= ffestorag_modulo (cst
)
7934 + ffestorag_offset (st
)
7935 - ffestorag_offset (cst
);
7937 ffecom_debug_kludge_ (ct
, "COMMON", s
, type
, offset
);
7939 /* (t_type *) (((char *) &ct) + offset) */
7941 t
= convert (string_type_node
, /* (char *) */
7942 ffecom_1 (ADDR_EXPR
,
7943 build_pointer_type (TREE_TYPE (ct
)),
7945 t
= ffecom_2 (PLUS_EXPR
, TREE_TYPE (t
),
7947 build_int_2 (offset
, 0));
7948 t
= convert (build_pointer_type (type
),
7950 TREE_CONSTANT (t
) = 1;
7957 case FFEINFO_whereIMMEDIATE
:
7958 case FFEINFO_whereGLOBAL
:
7959 case FFEINFO_whereFLEETING
:
7960 case FFEINFO_whereFLEETING_CADDR
:
7961 case FFEINFO_whereFLEETING_IADDR
:
7962 case FFEINFO_whereINTRINSIC
:
7963 case FFEINFO_whereCONSTANT_SUBOBJECT
:
7965 assert ("ENTITY where unheard of" == NULL
);
7967 case FFEINFO_whereANY
:
7968 t
= error_mark_node
;
7973 case FFEINFO_kindFUNCTION
:
7974 switch (ffeinfo_where (ffesymbol_info (s
)))
7976 case FFEINFO_whereLOCAL
: /* Me. */
7977 assert (!ffecom_transform_only_dummies_
);
7978 t
= current_function_decl
;
7981 case FFEINFO_whereGLOBAL
:
7982 assert (!ffecom_transform_only_dummies_
);
7984 if (((g
= ffesymbol_global (s
)) != NULL
)
7985 && ((ffeglobal_type (g
) == FFEGLOBAL_typeFUNC
)
7986 || (ffeglobal_type (g
) == FFEGLOBAL_typeEXT
))
7987 && (ffeglobal_hook (g
) != NULL_TREE
)
7988 && ffe_is_globals ())
7990 t
= ffeglobal_hook (g
);
7994 if (ffesymbol_is_f2c (s
)
7995 && (ffesymbol_where (s
) != FFEINFO_whereCONSTANT
))
7996 t
= ffecom_tree_fun_type
[bt
][kt
];
7998 t
= build_function_type (ffecom_tree_type
[bt
][kt
], NULL_TREE
);
8000 t
= build_decl (FUNCTION_DECL
,
8001 ffecom_get_external_identifier_ (s
),
8003 DECL_EXTERNAL (t
) = 1;
8004 TREE_PUBLIC (t
) = 1;
8006 t
= start_decl (t
, FALSE
);
8007 finish_decl (t
, NULL_TREE
, FALSE
);
8010 && ((ffeglobal_type (g
) == FFEGLOBAL_typeFUNC
)
8011 || (ffeglobal_type (g
) == FFEGLOBAL_typeEXT
)))
8012 ffeglobal_set_hook (g
, t
);
8014 ffecom_save_tree_forever (t
);
8018 case FFEINFO_whereDUMMY
:
8019 assert (ffecom_transform_only_dummies_
);
8021 if (ffesymbol_is_f2c (s
)
8022 && (ffesymbol_where (s
) != FFEINFO_whereCONSTANT
))
8023 t
= ffecom_tree_ptr_to_fun_type
[bt
][kt
];
8025 t
= build_pointer_type
8026 (build_function_type (ffecom_tree_type
[bt
][kt
], NULL_TREE
));
8028 t
= build_decl (PARM_DECL
,
8029 ffecom_get_identifier_ (ffesymbol_text (s
)),
8031 DECL_ARTIFICIAL (t
) = 1;
8035 case FFEINFO_whereCONSTANT
: /* Statement function. */
8036 assert (!ffecom_transform_only_dummies_
);
8037 t
= ffecom_gen_sfuncdef_ (s
, bt
, kt
);
8040 case FFEINFO_whereINTRINSIC
:
8041 assert (!ffecom_transform_only_dummies_
);
8042 break; /* Let actual references generate their
8046 assert ("FUNCTION where unheard of" == NULL
);
8048 case FFEINFO_whereANY
:
8049 t
= error_mark_node
;
8054 case FFEINFO_kindSUBROUTINE
:
8055 switch (ffeinfo_where (ffesymbol_info (s
)))
8057 case FFEINFO_whereLOCAL
: /* Me. */
8058 assert (!ffecom_transform_only_dummies_
);
8059 t
= current_function_decl
;
8062 case FFEINFO_whereGLOBAL
:
8063 assert (!ffecom_transform_only_dummies_
);
8065 if (((g
= ffesymbol_global (s
)) != NULL
)
8066 && ((ffeglobal_type (g
) == FFEGLOBAL_typeSUBR
)
8067 || (ffeglobal_type (g
) == FFEGLOBAL_typeEXT
))
8068 && (ffeglobal_hook (g
) != NULL_TREE
)
8069 && ffe_is_globals ())
8071 t
= ffeglobal_hook (g
);
8075 t
= build_decl (FUNCTION_DECL
,
8076 ffecom_get_external_identifier_ (s
),
8077 ffecom_tree_subr_type
);
8078 DECL_EXTERNAL (t
) = 1;
8079 TREE_PUBLIC (t
) = 1;
8081 t
= start_decl (t
, TRUE
);
8082 finish_decl (t
, NULL_TREE
, TRUE
);
8085 && ((ffeglobal_type (g
) == FFEGLOBAL_typeSUBR
)
8086 || (ffeglobal_type (g
) == FFEGLOBAL_typeEXT
)))
8087 ffeglobal_set_hook (g
, t
);
8089 ffecom_save_tree_forever (t
);
8093 case FFEINFO_whereDUMMY
:
8094 assert (ffecom_transform_only_dummies_
);
8096 t
= build_decl (PARM_DECL
,
8097 ffecom_get_identifier_ (ffesymbol_text (s
)),
8098 ffecom_tree_ptr_to_subr_type
);
8099 DECL_ARTIFICIAL (t
) = 1;
8103 case FFEINFO_whereINTRINSIC
:
8104 assert (!ffecom_transform_only_dummies_
);
8105 break; /* Let actual references generate their
8109 assert ("SUBROUTINE where unheard of" == NULL
);
8111 case FFEINFO_whereANY
:
8112 t
= error_mark_node
;
8117 case FFEINFO_kindPROGRAM
:
8118 switch (ffeinfo_where (ffesymbol_info (s
)))
8120 case FFEINFO_whereLOCAL
: /* Me. */
8121 assert (!ffecom_transform_only_dummies_
);
8122 t
= current_function_decl
;
8125 case FFEINFO_whereCOMMON
:
8126 case FFEINFO_whereDUMMY
:
8127 case FFEINFO_whereGLOBAL
:
8128 case FFEINFO_whereRESULT
:
8129 case FFEINFO_whereFLEETING
:
8130 case FFEINFO_whereFLEETING_CADDR
:
8131 case FFEINFO_whereFLEETING_IADDR
:
8132 case FFEINFO_whereIMMEDIATE
:
8133 case FFEINFO_whereINTRINSIC
:
8134 case FFEINFO_whereCONSTANT
:
8135 case FFEINFO_whereCONSTANT_SUBOBJECT
:
8137 assert ("PROGRAM where unheard of" == NULL
);
8139 case FFEINFO_whereANY
:
8140 t
= error_mark_node
;
8145 case FFEINFO_kindBLOCKDATA
:
8146 switch (ffeinfo_where (ffesymbol_info (s
)))
8148 case FFEINFO_whereLOCAL
: /* Me. */
8149 assert (!ffecom_transform_only_dummies_
);
8150 t
= current_function_decl
;
8153 case FFEINFO_whereGLOBAL
:
8154 assert (!ffecom_transform_only_dummies_
);
8156 t
= build_decl (FUNCTION_DECL
,
8157 ffecom_get_external_identifier_ (s
),
8158 ffecom_tree_blockdata_type
);
8159 DECL_EXTERNAL (t
) = 1;
8160 TREE_PUBLIC (t
) = 1;
8162 t
= start_decl (t
, FALSE
);
8163 finish_decl (t
, NULL_TREE
, FALSE
);
8165 ffecom_save_tree_forever (t
);
8169 case FFEINFO_whereCOMMON
:
8170 case FFEINFO_whereDUMMY
:
8171 case FFEINFO_whereRESULT
:
8172 case FFEINFO_whereFLEETING
:
8173 case FFEINFO_whereFLEETING_CADDR
:
8174 case FFEINFO_whereFLEETING_IADDR
:
8175 case FFEINFO_whereIMMEDIATE
:
8176 case FFEINFO_whereINTRINSIC
:
8177 case FFEINFO_whereCONSTANT
:
8178 case FFEINFO_whereCONSTANT_SUBOBJECT
:
8180 assert ("BLOCKDATA where unheard of" == NULL
);
8182 case FFEINFO_whereANY
:
8183 t
= error_mark_node
;
8188 case FFEINFO_kindCOMMON
:
8189 switch (ffeinfo_where (ffesymbol_info (s
)))
8191 case FFEINFO_whereLOCAL
:
8192 assert (!ffecom_transform_only_dummies_
);
8193 ffecom_transform_common_ (s
);
8196 case FFEINFO_whereNONE
:
8197 case FFEINFO_whereCOMMON
:
8198 case FFEINFO_whereDUMMY
:
8199 case FFEINFO_whereGLOBAL
:
8200 case FFEINFO_whereRESULT
:
8201 case FFEINFO_whereFLEETING
:
8202 case FFEINFO_whereFLEETING_CADDR
:
8203 case FFEINFO_whereFLEETING_IADDR
:
8204 case FFEINFO_whereIMMEDIATE
:
8205 case FFEINFO_whereINTRINSIC
:
8206 case FFEINFO_whereCONSTANT
:
8207 case FFEINFO_whereCONSTANT_SUBOBJECT
:
8209 assert ("COMMON where unheard of" == NULL
);
8211 case FFEINFO_whereANY
:
8212 t
= error_mark_node
;
8217 case FFEINFO_kindCONSTRUCT
:
8218 switch (ffeinfo_where (ffesymbol_info (s
)))
8220 case FFEINFO_whereLOCAL
:
8221 assert (!ffecom_transform_only_dummies_
);
8224 case FFEINFO_whereNONE
:
8225 case FFEINFO_whereCOMMON
:
8226 case FFEINFO_whereDUMMY
:
8227 case FFEINFO_whereGLOBAL
:
8228 case FFEINFO_whereRESULT
:
8229 case FFEINFO_whereFLEETING
:
8230 case FFEINFO_whereFLEETING_CADDR
:
8231 case FFEINFO_whereFLEETING_IADDR
:
8232 case FFEINFO_whereIMMEDIATE
:
8233 case FFEINFO_whereINTRINSIC
:
8234 case FFEINFO_whereCONSTANT
:
8235 case FFEINFO_whereCONSTANT_SUBOBJECT
:
8237 assert ("CONSTRUCT where unheard of" == NULL
);
8239 case FFEINFO_whereANY
:
8240 t
= error_mark_node
;
8245 case FFEINFO_kindNAMELIST
:
8246 switch (ffeinfo_where (ffesymbol_info (s
)))
8248 case FFEINFO_whereLOCAL
:
8249 assert (!ffecom_transform_only_dummies_
);
8250 t
= ffecom_transform_namelist_ (s
);
8253 case FFEINFO_whereNONE
:
8254 case FFEINFO_whereCOMMON
:
8255 case FFEINFO_whereDUMMY
:
8256 case FFEINFO_whereGLOBAL
:
8257 case FFEINFO_whereRESULT
:
8258 case FFEINFO_whereFLEETING
:
8259 case FFEINFO_whereFLEETING_CADDR
:
8260 case FFEINFO_whereFLEETING_IADDR
:
8261 case FFEINFO_whereIMMEDIATE
:
8262 case FFEINFO_whereINTRINSIC
:
8263 case FFEINFO_whereCONSTANT
:
8264 case FFEINFO_whereCONSTANT_SUBOBJECT
:
8266 assert ("NAMELIST where unheard of" == NULL
);
8268 case FFEINFO_whereANY
:
8269 t
= error_mark_node
;
8275 assert ("kind unheard of" == NULL
);
8277 case FFEINFO_kindANY
:
8278 t
= error_mark_node
;
8282 ffesymbol_hook (s
).decl_tree
= t
;
8283 ffesymbol_hook (s
).length_tree
= tlen
;
8284 ffesymbol_hook (s
).addr
= addr
;
8286 input_location
= old_loc
;
8291 /* Transform into ASSIGNable symbol.
8293 Symbol has already been transformed, but for whatever reason, the
8294 resulting decl_tree has been deemed not usable for an ASSIGN target.
8295 (E.g. it isn't wide enough to hold a pointer.) So, here we invent
8296 another local symbol of type void * and stuff that in the assign_tree
8297 argument. The F77/F90 standards allow this implementation. */
8300 ffecom_sym_transform_assign_ (ffesymbol s
)
8302 tree t
; /* Transformed thingy. */
8303 location_t old_loc
= input_location
;
8305 if (ffesymbol_sfdummyparent (s
) == NULL
)
8307 input_filename
= ffesymbol_where_filename (s
);
8308 input_line
= ffesymbol_where_filelinenum (s
);
8312 ffesymbol sf
= ffesymbol_sfdummyparent (s
);
8314 input_filename
= ffesymbol_where_filename (sf
);
8315 input_line
= ffesymbol_where_filelinenum (sf
);
8318 assert (!ffecom_transform_only_dummies_
);
8320 t
= build_decl (VAR_DECL
,
8321 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
8322 ffesymbol_text (s
)),
8323 TREE_TYPE (null_pointer_node
));
8325 switch (ffesymbol_where (s
))
8327 case FFEINFO_whereLOCAL
:
8328 /* Unlike for regular vars, SAVE status is easy to determine for
8329 ASSIGNed vars, since there's no initialization, there's no
8330 effective storage association (so "SAVE J" does not apply to
8331 K even given "EQUIVALENCE (J,K)"), there's no size issue
8332 to worry about, etc. */
8333 if ((ffesymbol_is_save (s
) || ffe_is_saveall ())
8334 && (ffecom_primary_entry_kind_
!= FFEINFO_kindPROGRAM
)
8335 && (ffecom_primary_entry_kind_
!= FFEINFO_kindBLOCKDATA
))
8336 TREE_STATIC (t
) = 1; /* SAVEd in proc, make static. */
8338 TREE_STATIC (t
) = 0; /* No need to make static. */
8341 case FFEINFO_whereCOMMON
:
8342 TREE_STATIC (t
) = 1; /* Assume COMMONs always SAVEd. */
8345 case FFEINFO_whereDUMMY
:
8346 /* Note that twinning a DUMMY means the caller won't see
8347 the ASSIGNed value. But both F77 and F90 allow implementations
8348 to do this, i.e. disallow Fortran code that would try and
8349 take advantage of actually putting a label into a variable
8350 via a dummy argument (or any other storage association, for
8352 TREE_STATIC (t
) = 0;
8356 TREE_STATIC (t
) = 0;
8360 t
= start_decl (t
, FALSE
);
8361 finish_decl (t
, NULL_TREE
, FALSE
);
8363 ffesymbol_hook (s
).assign_tree
= t
;
8365 input_location
= old_loc
;
8370 /* Implement COMMON area in back end.
8372 Because COMMON-based variables can be referenced in the dimension
8373 expressions of dummy (adjustable) arrays, and because dummies
8374 (in the gcc back end) need to be put in the outer binding level
8375 of a function (which has two binding levels, the outer holding
8376 the dummies and the inner holding the other vars), special care
8377 must be taken to handle COMMON areas.
8379 The current strategy is basically to always tell the back end about
8380 the COMMON area as a top-level external reference to just a block
8381 of storage of the master type of that area (e.g. integer, real,
8382 character, whatever -- not a structure). As a distinct action,
8383 if initial values are provided, tell the back end about the area
8384 as a top-level non-external (initialized) area and remember not to
8385 allow further initialization or expansion of the area. Meanwhile,
8386 if no initialization happens at all, tell the back end about
8387 the largest size we've seen declared so the space does get reserved.
8388 (This function doesn't handle all that stuff, but it does some
8389 of the important things.)
8391 Meanwhile, for COMMON variables themselves, just keep creating
8392 references like *((float *) (&common_area + offset)) each time
8393 we reference the variable. In other words, don't make a VAR_DECL
8394 or any kind of component reference (like we used to do before 0.4),
8395 though we might do that as well just for debugging purposes (and
8396 stuff the rtl with the appropriate offset expression). */
8399 ffecom_transform_common_ (ffesymbol s
)
8401 ffestorag st
= ffesymbol_storage (s
);
8402 ffeglobal g
= ffesymbol_global (s
);
8407 bool is_init
= ffestorag_is_init (st
);
8409 assert (st
!= NULL
);
8412 || (ffeglobal_type (g
) != FFEGLOBAL_typeCOMMON
))
8415 /* First update the size of the area in global terms. */
8417 ffeglobal_size_common (s
, ffestorag_size (st
));
8419 if (!ffeglobal_common_init (g
))
8420 is_init
= FALSE
; /* No explicit init, don't let erroneous joins init. */
8422 cbt
= ffeglobal_hook (g
);
8424 /* If we already have declared this common block for a previous program
8425 unit, and either we already initialized it or we don't have new
8426 initialization for it, just return what we have without changing it. */
8428 if ((cbt
!= NULL_TREE
)
8430 || !DECL_EXTERNAL (cbt
)))
8432 if (st
->hook
== NULL
) ffestorag_set_hook (st
, cbt
);
8436 /* Process inits. */
8440 if (ffestorag_init (st
) != NULL
)
8444 /* Set the padding for the expression, so ffecom_expr
8445 knows to insert that many zeros. */
8446 switch (ffebld_op (sexp
= ffestorag_init (st
)))
8448 case FFEBLD_opCONTER
:
8449 ffebld_conter_set_pad (sexp
, ffestorag_modulo (st
));
8452 case FFEBLD_opARRTER
:
8453 ffebld_arrter_set_pad (sexp
, ffestorag_modulo (st
));
8456 case FFEBLD_opACCTER
:
8457 ffebld_accter_set_pad (sexp
, ffestorag_modulo (st
));
8461 assert ("bad op for cmn init (pad)" == NULL
);
8465 init
= ffecom_expr (sexp
);
8466 if (init
== error_mark_node
)
8467 { /* Hopefully the back end complained! */
8469 if (cbt
!= NULL_TREE
)
8474 init
= error_mark_node
;
8479 /* cbtype must be permanently allocated! */
8481 /* Allocate the MAX of the areas so far, seen filewide. */
8482 high
= build_int_2 ((ffeglobal_common_size (g
)
8483 + ffeglobal_common_pad (g
)) - 1, 0);
8484 TREE_TYPE (high
) = ffecom_integer_type_node
;
8487 cbtype
= build_array_type (char_type_node
,
8488 build_range_type (integer_type_node
,
8492 cbtype
= build_array_type (char_type_node
, NULL_TREE
);
8494 if (cbt
== NULL_TREE
)
8497 = build_decl (VAR_DECL
,
8498 ffecom_get_external_identifier_ (s
),
8500 TREE_STATIC (cbt
) = 1;
8501 TREE_PUBLIC (cbt
) = 1;
8506 TREE_TYPE (cbt
) = cbtype
;
8508 DECL_EXTERNAL (cbt
) = init
? 0 : 1;
8509 DECL_INITIAL (cbt
) = init
? error_mark_node
: NULL_TREE
;
8511 cbt
= start_decl (cbt
, TRUE
);
8512 if (ffeglobal_hook (g
) != NULL
)
8513 assert (cbt
== ffeglobal_hook (g
));
8515 assert (!init
|| !DECL_EXTERNAL (cbt
));
8517 /* Make sure that any type can live in COMMON and be referenced
8518 without getting a bus error. We could pick the most restrictive
8519 alignment of all entities actually placed in the COMMON, but
8520 this seems easy enough. */
8522 DECL_ALIGN (cbt
) = BIGGEST_ALIGNMENT
;
8523 DECL_USER_ALIGN (cbt
) = 0;
8525 if (is_init
&& (ffestorag_init (st
) == NULL
))
8526 init
= ffecom_init_zero_ (cbt
);
8528 finish_decl (cbt
, init
, TRUE
);
8531 ffestorag_set_init (st
, ffebld_new_any ());
8535 assert (DECL_SIZE_UNIT (cbt
) != NULL_TREE
);
8536 assert (TREE_CODE (DECL_SIZE_UNIT (cbt
)) == INTEGER_CST
);
8537 assert (0 == compare_tree_int (DECL_SIZE_UNIT (cbt
),
8538 (ffeglobal_common_size (g
)
8539 + ffeglobal_common_pad (g
))));
8542 ffeglobal_set_hook (g
, cbt
);
8544 ffestorag_set_hook (st
, cbt
);
8546 ffecom_save_tree_forever (cbt
);
8549 /* Make master area for local EQUIVALENCE. */
8552 ffecom_transform_equiv_ (ffestorag eqst
)
8558 bool is_init
= ffestorag_is_init (eqst
);
8560 assert (eqst
!= NULL
);
8562 eqt
= ffestorag_hook (eqst
);
8564 if (eqt
!= NULL_TREE
)
8567 /* Process inits. */
8571 if (ffestorag_init (eqst
) != NULL
)
8575 /* Set the padding for the expression, so ffecom_expr
8576 knows to insert that many zeros. */
8577 switch (ffebld_op (sexp
= ffestorag_init (eqst
)))
8579 case FFEBLD_opCONTER
:
8580 ffebld_conter_set_pad (sexp
, ffestorag_modulo (eqst
));
8583 case FFEBLD_opARRTER
:
8584 ffebld_arrter_set_pad (sexp
, ffestorag_modulo (eqst
));
8587 case FFEBLD_opACCTER
:
8588 ffebld_accter_set_pad (sexp
, ffestorag_modulo (eqst
));
8592 assert ("bad op for eqv init (pad)" == NULL
);
8596 init
= ffecom_expr (sexp
);
8597 if (init
== error_mark_node
)
8598 init
= NULL_TREE
; /* Hopefully the back end complained! */
8601 init
= error_mark_node
;
8603 else if (ffe_is_init_local_zero ())
8604 init
= error_mark_node
;
8608 ffecom_member_namelisted_
= FALSE
;
8609 ffestorag_drive (ffestorag_list_equivs (eqst
),
8610 &ffecom_member_phase1_
,
8613 high
= build_int_2 ((ffestorag_size (eqst
)
8614 + ffestorag_modulo (eqst
)) - 1, 0);
8615 TREE_TYPE (high
) = ffecom_integer_type_node
;
8617 eqtype
= build_array_type (char_type_node
,
8618 build_range_type (ffecom_integer_type_node
,
8619 ffecom_integer_zero_node
,
8622 eqt
= build_decl (VAR_DECL
,
8623 ffecom_get_invented_identifier ("__g77_equiv_%s",
8625 (ffestorag_symbol (eqst
))),
8627 DECL_EXTERNAL (eqt
) = 0;
8629 || ffecom_member_namelisted_
8630 #ifdef FFECOM_sizeMAXSTACKITEM
8631 || (ffestorag_size (eqst
) > FFECOM_sizeMAXSTACKITEM
)
8633 || ((ffecom_primary_entry_kind_
!= FFEINFO_kindPROGRAM
)
8634 && (ffecom_primary_entry_kind_
!= FFEINFO_kindBLOCKDATA
)
8635 && (ffestorag_is_save (eqst
) || ffe_is_saveall ())))
8636 TREE_STATIC (eqt
) = 1;
8638 TREE_STATIC (eqt
) = 0;
8639 TREE_PUBLIC (eqt
) = 0;
8640 TREE_ADDRESSABLE (eqt
) = 1; /* Ensure non-register allocation */
8641 DECL_CONTEXT (eqt
) = current_function_decl
;
8643 DECL_INITIAL (eqt
) = error_mark_node
;
8645 DECL_INITIAL (eqt
) = NULL_TREE
;
8647 eqt
= start_decl (eqt
, FALSE
);
8649 /* Make sure that any type can live in EQUIVALENCE and be referenced
8650 without getting a bus error. We could pick the most restrictive
8651 alignment of all entities actually placed in the EQUIVALENCE, but
8652 this seems easy enough. */
8654 DECL_ALIGN (eqt
) = BIGGEST_ALIGNMENT
;
8655 DECL_USER_ALIGN (eqt
) = 0;
8657 if ((!is_init
&& ffe_is_init_local_zero ())
8658 || (is_init
&& (ffestorag_init (eqst
) == NULL
)))
8659 init
= ffecom_init_zero_ (eqt
);
8661 finish_decl (eqt
, init
, FALSE
);
8664 ffestorag_set_init (eqst
, ffebld_new_any ());
8667 assert (TREE_CODE (DECL_SIZE_UNIT (eqt
)) == INTEGER_CST
);
8668 assert (0 == compare_tree_int (DECL_SIZE_UNIT (eqt
),
8669 (ffestorag_size (eqst
)
8670 + ffestorag_modulo (eqst
))));
8673 ffestorag_set_hook (eqst
, eqt
);
8675 ffestorag_drive (ffestorag_list_equivs (eqst
),
8676 &ffecom_member_phase2_
,
8680 /* Implement NAMELIST in back end. See f2c/format.c for more info. */
8683 ffecom_transform_namelist_ (ffesymbol s
)
8686 tree nmltype
= ffecom_type_namelist_ ();
8694 static int mynumber
= 0;
8696 nmlt
= build_decl (VAR_DECL
,
8697 ffecom_get_invented_identifier ("__g77_namelist_%d",
8700 TREE_STATIC (nmlt
) = 1;
8701 DECL_INITIAL (nmlt
) = error_mark_node
;
8703 nmlt
= start_decl (nmlt
, FALSE
);
8705 /* Process inits. */
8707 i
= strlen (ffesymbol_text (s
));
8709 high
= build_int_2 (i
, 0);
8710 TREE_TYPE (high
) = ffecom_f2c_ftnlen_type_node
;
8712 nameinit
= ffecom_build_f2c_string_ (i
+ 1,
8713 ffesymbol_text (s
));
8714 TREE_TYPE (nameinit
)
8715 = build_type_variant
8718 build_range_type (ffecom_f2c_ftnlen_type_node
,
8719 ffecom_f2c_ftnlen_one_node
,
8722 TREE_CONSTANT (nameinit
) = 1;
8723 TREE_STATIC (nameinit
) = 1;
8724 nameinit
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (nameinit
)),
8727 varsinit
= ffecom_vardesc_array_ (s
);
8728 varsinit
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (varsinit
)),
8730 TREE_CONSTANT (varsinit
) = 1;
8731 TREE_STATIC (varsinit
) = 1;
8736 for (i
= 0, b
= ffesymbol_namelist (s
); b
!= NULL
; b
= ffebld_trail (b
))
8739 nvarsinit
= build_int_2 (i
, 0);
8740 TREE_TYPE (nvarsinit
) = integer_type_node
;
8741 TREE_CONSTANT (nvarsinit
) = 1;
8742 TREE_STATIC (nvarsinit
) = 1;
8744 nmlinits
= build_tree_list ((field
= TYPE_FIELDS (nmltype
)), nameinit
);
8745 TREE_CHAIN (nmlinits
) = build_tree_list ((field
= TREE_CHAIN (field
)),
8747 TREE_CHAIN (TREE_CHAIN (nmlinits
))
8748 = build_tree_list ((field
= TREE_CHAIN (field
)), nvarsinit
);
8750 nmlinits
= build_constructor (nmltype
, nmlinits
);
8751 TREE_CONSTANT (nmlinits
) = 1;
8752 TREE_STATIC (nmlinits
) = 1;
8754 finish_decl (nmlt
, nmlinits
, FALSE
);
8756 nmlt
= ffecom_1 (ADDR_EXPR
, build_pointer_type (nmltype
), nmlt
);
8761 /* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is
8762 analyzed on the assumption it is calculating a pointer to be
8763 indirected through. It must return the proper decl and offset,
8764 taking into account different units of measurements for offsets. */
8767 ffecom_tree_canonize_ptr_ (tree
*decl
, tree
*offset
,
8770 switch (TREE_CODE (t
))
8774 case NON_LVALUE_EXPR
:
8775 ffecom_tree_canonize_ptr_ (decl
, offset
, TREE_OPERAND (t
, 0));
8779 ffecom_tree_canonize_ptr_ (decl
, offset
, TREE_OPERAND (t
, 0));
8780 if ((*decl
== NULL_TREE
)
8781 || (*decl
== error_mark_node
))
8784 if (TREE_CODE (TREE_OPERAND (t
, 1)) == INTEGER_CST
)
8786 /* An offset into COMMON. */
8787 *offset
= fold (build (PLUS_EXPR
, TREE_TYPE (*offset
),
8788 *offset
, TREE_OPERAND (t
, 1)));
8789 /* Convert offset (presumably in bytes) into canonical units
8790 (presumably bits). */
8791 *offset
= size_binop (MULT_EXPR
,
8792 convert (bitsizetype
, *offset
),
8793 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t
))));
8796 /* Not a COMMON reference, so an unrecognized pattern. */
8797 *decl
= error_mark_node
;
8802 *offset
= bitsize_zero_node
;
8806 if (TREE_CODE (TREE_OPERAND (t
, 0)) == VAR_DECL
)
8808 /* A reference to COMMON. */
8809 *decl
= TREE_OPERAND (t
, 0);
8810 *offset
= bitsize_zero_node
;
8815 /* Not a COMMON reference, so an unrecognized pattern. */
8816 *decl
= error_mark_node
;
8821 /* Given a tree that is possibly intended for use as an lvalue, return
8822 information representing a canonical view of that tree as a decl, an
8823 offset into that decl, and a size for the lvalue.
8825 If there's no applicable decl, NULL_TREE is returned for the decl,
8826 and the other fields are left undefined.
8828 If the tree doesn't fit the recognizable forms, an ERROR_MARK node
8829 is returned for the decl, and the other fields are left undefined.
8831 Otherwise, the decl returned currently is either a VAR_DECL or a
8834 The offset returned is always valid, but of course not necessarily
8835 a constant, and not necessarily converted into the appropriate
8836 type, leaving that up to the caller (so as to avoid that overhead
8837 if the decls being looked at are different anyway).
8839 If the size cannot be determined (e.g. an adjustable array),
8840 an ERROR_MARK node is returned for the size. Otherwise, the
8841 size returned is valid, not necessarily a constant, and not
8842 necessarily converted into the appropriate type as with the
8845 Note that the offset and size expressions are expressed in the
8846 base storage units (usually bits) rather than in the units of
8847 the type of the decl, because two decls with different types
8848 might overlap but with apparently non-overlapping array offsets,
8849 whereas converting the array offsets to consistant offsets will
8850 reveal the overlap. */
8853 ffecom_tree_canonize_ref_ (tree
*decl
, tree
*offset
,
8856 /* The default path is to report a nonexistant decl. */
8862 switch (TREE_CODE (t
))
8865 case IDENTIFIER_NODE
:
8874 case TRUNC_DIV_EXPR
:
8876 case FLOOR_DIV_EXPR
:
8877 case ROUND_DIV_EXPR
:
8878 case TRUNC_MOD_EXPR
:
8880 case FLOOR_MOD_EXPR
:
8881 case ROUND_MOD_EXPR
:
8883 case EXACT_DIV_EXPR
:
8884 case FIX_TRUNC_EXPR
:
8886 case FIX_FLOOR_EXPR
:
8887 case FIX_ROUND_EXPR
:
8901 case BIT_ANDTC_EXPR
:
8903 case TRUTH_ANDIF_EXPR
:
8904 case TRUTH_ORIF_EXPR
:
8905 case TRUTH_AND_EXPR
:
8907 case TRUTH_XOR_EXPR
:
8908 case TRUTH_NOT_EXPR
:
8928 *offset
= bitsize_zero_node
;
8929 *size
= TYPE_SIZE (TREE_TYPE (t
));
8934 tree array
= TREE_OPERAND (t
, 0);
8935 tree element
= TREE_OPERAND (t
, 1);
8938 if ((array
== NULL_TREE
)
8939 || (element
== NULL_TREE
))
8941 *decl
= error_mark_node
;
8945 ffecom_tree_canonize_ref_ (decl
, &init_offset
, size
,
8947 if ((*decl
== NULL_TREE
)
8948 || (*decl
== error_mark_node
))
8951 /* Calculate ((element - base) * NBBY) + init_offset. */
8952 *offset
= fold (build (MINUS_EXPR
, TREE_TYPE (element
),
8954 TYPE_MIN_VALUE (TYPE_DOMAIN
8955 (TREE_TYPE (array
)))));
8957 *offset
= size_binop (MULT_EXPR
,
8958 convert (bitsizetype
, *offset
),
8959 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array
))));
8961 *offset
= size_binop (PLUS_EXPR
, init_offset
, *offset
);
8963 *size
= TYPE_SIZE (TREE_TYPE (t
));
8969 /* Most of this code is to handle references to COMMON. And so
8970 far that is useful only for calling library functions, since
8971 external (user) functions might reference common areas. But
8972 even calling an external function, it's worthwhile to decode
8973 COMMON references because if not storing into COMMON, we don't
8974 want COMMON-based arguments to gratuitously force use of a
8977 *size
= TYPE_SIZE (TREE_TYPE (t
));
8979 ffecom_tree_canonize_ptr_ (decl
, offset
,
8980 TREE_OPERAND (t
, 0));
8987 case NON_LVALUE_EXPR
:
8990 case COND_EXPR
: /* More cases than we can handle. */
8992 case REFERENCE_EXPR
:
8993 case PREDECREMENT_EXPR
:
8994 case PREINCREMENT_EXPR
:
8995 case POSTDECREMENT_EXPR
:
8996 case POSTINCREMENT_EXPR
:
8999 *decl
= error_mark_node
;
9004 /* Do divide operation appropriate to type of operands. */
9007 ffecom_tree_divide_ (tree tree_type
, tree left
, tree right
,
9008 tree dest_tree
, ffebld dest
, bool *dest_used
,
9011 if ((left
== error_mark_node
)
9012 || (right
== error_mark_node
))
9013 return error_mark_node
;
9015 switch (TREE_CODE (tree_type
))
9018 return ffecom_2 (TRUNC_DIV_EXPR
, tree_type
,
9023 if (! optimize_size
)
9024 return ffecom_2 (RDIV_EXPR
, tree_type
,
9030 if (TREE_TYPE (tree_type
)
9031 == ffecom_tree_type
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL1
])
9032 ix
= FFECOM_gfrtDIV_CC
; /* Overlapping result okay. */
9034 ix
= FFECOM_gfrtDIV_ZZ
; /* Overlapping result okay. */
9036 left
= ffecom_1 (ADDR_EXPR
,
9037 build_pointer_type (TREE_TYPE (left
)),
9039 left
= build_tree_list (NULL_TREE
, left
);
9040 right
= ffecom_1 (ADDR_EXPR
,
9041 build_pointer_type (TREE_TYPE (right
)),
9043 right
= build_tree_list (NULL_TREE
, right
);
9044 TREE_CHAIN (left
) = right
;
9046 return ffecom_call_ (ffecom_gfrt_tree_ (ix
),
9047 ffecom_gfrt_kindtype (ix
),
9048 ffe_is_f2c_library (),
9051 dest_tree
, dest
, dest_used
,
9052 NULL_TREE
, TRUE
, hook
);
9060 if (TREE_TYPE (TYPE_FIELDS (tree_type
))
9061 == ffecom_tree_type
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL1
])
9062 ix
= FFECOM_gfrtDIV_CC
; /* Overlapping result okay. */
9064 ix
= FFECOM_gfrtDIV_ZZ
; /* Overlapping result okay. */
9066 left
= ffecom_1 (ADDR_EXPR
,
9067 build_pointer_type (TREE_TYPE (left
)),
9069 left
= build_tree_list (NULL_TREE
, left
);
9070 right
= ffecom_1 (ADDR_EXPR
,
9071 build_pointer_type (TREE_TYPE (right
)),
9073 right
= build_tree_list (NULL_TREE
, right
);
9074 TREE_CHAIN (left
) = right
;
9076 return ffecom_call_ (ffecom_gfrt_tree_ (ix
),
9077 ffecom_gfrt_kindtype (ix
),
9078 ffe_is_f2c_library (),
9081 dest_tree
, dest
, dest_used
,
9082 NULL_TREE
, TRUE
, hook
);
9087 return ffecom_2 (RDIV_EXPR
, tree_type
,
9093 /* Build type info for non-dummy variable. */
9096 ffecom_type_localvar_ (ffesymbol s
, ffeinfoBasictype bt
,
9105 type
= ffecom_tree_type
[bt
][kt
];
9106 if (bt
== FFEINFO_basictypeCHARACTER
)
9108 hight
= build_int_2 (ffesymbol_size (s
), 0);
9109 TREE_TYPE (hight
) = ffecom_f2c_ftnlen_type_node
;
9114 build_range_type (ffecom_f2c_ftnlen_type_node
,
9115 ffecom_f2c_ftnlen_one_node
,
9117 type
= ffecom_check_size_overflow_ (s
, type
, FALSE
);
9120 for (dl
= ffesymbol_dims (s
); dl
!= NULL
; dl
= ffebld_trail (dl
))
9122 if (type
== error_mark_node
)
9125 dim
= ffebld_head (dl
);
9126 assert (ffebld_op (dim
) == FFEBLD_opBOUNDS
);
9128 if (ffebld_left (dim
) == NULL
)
9129 lowt
= integer_one_node
;
9131 lowt
= ffecom_expr (ffebld_left (dim
));
9133 if (TREE_CODE (lowt
) != INTEGER_CST
)
9134 lowt
= variable_size (lowt
);
9136 assert (ffebld_right (dim
) != NULL
);
9137 hight
= ffecom_expr (ffebld_right (dim
));
9139 if (TREE_CODE (hight
) != INTEGER_CST
)
9140 hight
= variable_size (hight
);
9142 type
= build_array_type (type
,
9143 build_range_type (ffecom_integer_type_node
,
9145 type
= ffecom_check_size_overflow_ (s
, type
, FALSE
);
9151 /* Build Namelist type. */
9153 static GTY(()) tree ffecom_type_namelist_var
;
9155 ffecom_type_namelist_ ()
9157 if (ffecom_type_namelist_var
== NULL_TREE
)
9159 tree namefield
, varsfield
, nvarsfield
, vardesctype
, type
;
9161 vardesctype
= ffecom_type_vardesc_ ();
9163 type
= make_node (RECORD_TYPE
);
9165 vardesctype
= build_pointer_type (build_pointer_type (vardesctype
));
9167 namefield
= ffecom_decl_field (type
, NULL_TREE
, "name",
9169 varsfield
= ffecom_decl_field (type
, namefield
, "vars", vardesctype
);
9170 nvarsfield
= ffecom_decl_field (type
, varsfield
, "nvars",
9173 TYPE_FIELDS (type
) = namefield
;
9176 ffecom_type_namelist_var
= type
;
9179 return ffecom_type_namelist_var
;
9182 /* Build Vardesc type. */
9184 static GTY(()) tree ffecom_type_vardesc_var
;
9186 ffecom_type_vardesc_ ()
9188 if (ffecom_type_vardesc_var
== NULL_TREE
)
9190 tree namefield
, addrfield
, dimsfield
, typefield
, type
;
9191 type
= make_node (RECORD_TYPE
);
9193 namefield
= ffecom_decl_field (type
, NULL_TREE
, "name",
9195 addrfield
= ffecom_decl_field (type
, namefield
, "addr",
9197 dimsfield
= ffecom_decl_field (type
, addrfield
, "dims",
9198 ffecom_f2c_ptr_to_ftnlen_type_node
);
9199 typefield
= ffecom_decl_field (type
, dimsfield
, "type",
9202 TYPE_FIELDS (type
) = namefield
;
9205 ffecom_type_vardesc_var
= type
;
9208 return ffecom_type_vardesc_var
;
9212 ffecom_vardesc_ (ffebld expr
)
9216 assert (ffebld_op (expr
) == FFEBLD_opSYMTER
);
9217 s
= ffebld_symter (expr
);
9219 if (ffesymbol_hook (s
).vardesc_tree
== NULL_TREE
)
9222 tree vardesctype
= ffecom_type_vardesc_ ();
9230 static int mynumber
= 0;
9232 var
= build_decl (VAR_DECL
,
9233 ffecom_get_invented_identifier ("__g77_vardesc_%d",
9236 TREE_STATIC (var
) = 1;
9237 DECL_INITIAL (var
) = error_mark_node
;
9239 var
= start_decl (var
, FALSE
);
9241 /* Process inits. */
9243 nameinit
= ffecom_build_f2c_string_ ((i
= strlen (ffesymbol_text (s
)))
9245 ffesymbol_text (s
));
9246 TREE_TYPE (nameinit
)
9247 = build_type_variant
9250 build_range_type (integer_type_node
,
9252 build_int_2 (i
, 0))),
9254 TREE_CONSTANT (nameinit
) = 1;
9255 TREE_STATIC (nameinit
) = 1;
9256 nameinit
= ffecom_1 (ADDR_EXPR
,
9257 build_pointer_type (TREE_TYPE (nameinit
)),
9260 addrinit
= ffecom_arg_ptr_to_expr (expr
, &typeinit
);
9262 dimsinit
= ffecom_vardesc_dims_ (s
);
9264 if (typeinit
== NULL_TREE
)
9266 ffeinfoBasictype bt
= ffesymbol_basictype (s
);
9267 ffeinfoKindtype kt
= ffesymbol_kindtype (s
);
9268 int tc
= ffecom_f2c_typecode (bt
, kt
);
9271 typeinit
= build_int_2 (tc
, (tc
< 0) ? -1 : 0);
9274 typeinit
= ffecom_1 (NEGATE_EXPR
, TREE_TYPE (typeinit
), typeinit
);
9276 varinits
= build_tree_list ((field
= TYPE_FIELDS (vardesctype
)),
9278 TREE_CHAIN (varinits
) = build_tree_list ((field
= TREE_CHAIN (field
)),
9280 TREE_CHAIN (TREE_CHAIN (varinits
))
9281 = build_tree_list ((field
= TREE_CHAIN (field
)), dimsinit
);
9282 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits
)))
9283 = build_tree_list ((field
= TREE_CHAIN (field
)), typeinit
);
9285 varinits
= build_constructor (vardesctype
, varinits
);
9286 TREE_CONSTANT (varinits
) = 1;
9287 TREE_STATIC (varinits
) = 1;
9289 finish_decl (var
, varinits
, FALSE
);
9291 var
= ffecom_1 (ADDR_EXPR
, build_pointer_type (vardesctype
), var
);
9293 ffesymbol_hook (s
).vardesc_tree
= var
;
9296 return ffesymbol_hook (s
).vardesc_tree
;
9300 ffecom_vardesc_array_ (ffesymbol s
)
9304 tree item
= NULL_TREE
;
9307 static int mynumber
= 0;
9309 for (i
= 0, list
= NULL_TREE
, b
= ffesymbol_namelist (s
);
9311 b
= ffebld_trail (b
), ++i
)
9315 t
= ffecom_vardesc_ (ffebld_head (b
));
9317 if (list
== NULL_TREE
)
9318 list
= item
= build_tree_list (NULL_TREE
, t
);
9321 TREE_CHAIN (item
) = build_tree_list (NULL_TREE
, t
);
9322 item
= TREE_CHAIN (item
);
9326 item
= build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
9327 build_range_type (integer_type_node
,
9329 build_int_2 (i
, 0)));
9330 list
= build_constructor (item
, list
);
9331 TREE_CONSTANT (list
) = 1;
9332 TREE_STATIC (list
) = 1;
9334 var
= ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber
++);
9335 var
= build_decl (VAR_DECL
, var
, item
);
9336 TREE_STATIC (var
) = 1;
9337 DECL_INITIAL (var
) = error_mark_node
;
9338 var
= start_decl (var
, FALSE
);
9339 finish_decl (var
, list
, FALSE
);
9345 ffecom_vardesc_dims_ (ffesymbol s
)
9347 if (ffesymbol_dims (s
) == NULL
)
9348 return convert (ffecom_f2c_ptr_to_ftnlen_type_node
,
9356 tree item
= NULL_TREE
;
9360 tree baseoff
= NULL_TREE
;
9361 static int mynumber
= 0;
9363 numdim
= build_int_2 ((int) ffesymbol_rank (s
), 0);
9364 TREE_TYPE (numdim
) = ffecom_f2c_ftnlen_type_node
;
9366 numelem
= ffecom_expr (ffesymbol_arraysize (s
));
9367 TREE_TYPE (numelem
) = ffecom_f2c_ftnlen_type_node
;
9370 backlist
= NULL_TREE
;
9371 for (b
= ffesymbol_dims (s
), e
= ffesymbol_extents (s
);
9373 b
= ffebld_trail (b
), e
= ffebld_trail (e
))
9379 if (ffebld_trail (b
) == NULL
)
9383 t
= convert (ffecom_f2c_ftnlen_type_node
,
9384 ffecom_expr (ffebld_head (e
)));
9386 if (list
== NULL_TREE
)
9387 list
= item
= build_tree_list (NULL_TREE
, t
);
9390 TREE_CHAIN (item
) = build_tree_list (NULL_TREE
, t
);
9391 item
= TREE_CHAIN (item
);
9395 if (ffebld_left (ffebld_head (b
)) == NULL
)
9396 low
= ffecom_integer_one_node
;
9398 low
= ffecom_expr (ffebld_left (ffebld_head (b
)));
9399 low
= convert (ffecom_f2c_ftnlen_type_node
, low
);
9401 back
= build_tree_list (low
, t
);
9402 TREE_CHAIN (back
) = backlist
;
9406 for (item
= backlist
; item
!= NULL_TREE
; item
= TREE_CHAIN (item
))
9408 if (TREE_VALUE (item
) == NULL_TREE
)
9409 baseoff
= TREE_PURPOSE (item
);
9411 baseoff
= ffecom_2 (PLUS_EXPR
, ffecom_f2c_ftnlen_type_node
,
9412 TREE_PURPOSE (item
),
9413 ffecom_2 (MULT_EXPR
,
9414 ffecom_f2c_ftnlen_type_node
,
9419 /* backlist now dead, along with all TREE_PURPOSEs on it. */
9421 baseoff
= build_tree_list (NULL_TREE
, baseoff
);
9422 TREE_CHAIN (baseoff
) = list
;
9424 numelem
= build_tree_list (NULL_TREE
, numelem
);
9425 TREE_CHAIN (numelem
) = baseoff
;
9427 numdim
= build_tree_list (NULL_TREE
, numdim
);
9428 TREE_CHAIN (numdim
) = numelem
;
9430 item
= build_array_type (ffecom_f2c_ftnlen_type_node
,
9431 build_range_type (integer_type_node
,
9434 ((int) ffesymbol_rank (s
)
9436 list
= build_constructor (item
, numdim
);
9437 TREE_CONSTANT (list
) = 1;
9438 TREE_STATIC (list
) = 1;
9440 var
= ffecom_get_invented_identifier ("__g77_dims_%d", mynumber
++);
9441 var
= build_decl (VAR_DECL
, var
, item
);
9442 TREE_STATIC (var
) = 1;
9443 DECL_INITIAL (var
) = error_mark_node
;
9444 var
= start_decl (var
, FALSE
);
9445 finish_decl (var
, list
, FALSE
);
9447 var
= ffecom_1 (ADDR_EXPR
, build_pointer_type (item
), var
);
9453 /* Essentially does a "fold (build1 (code, type, node))" while checking
9454 for certain housekeeping things.
9456 NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use
9457 ffecom_1_fn instead. */
9460 ffecom_1 (enum tree_code code
, tree type
, tree node
)
9464 if ((node
== error_mark_node
)
9465 || (type
== error_mark_node
))
9466 return error_mark_node
;
9468 if (code
== ADDR_EXPR
)
9470 if (!ffe_mark_addressable (node
))
9471 assert ("can't mark_addressable this node!" == NULL
);
9474 switch (ffe_is_emulate_complex () ? code
: NOP_EXPR
)
9479 item
= build (COMPONENT_REF
, type
, node
, TYPE_FIELDS (TREE_TYPE (node
)));
9483 item
= build (COMPONENT_REF
, type
, node
, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node
))));
9488 if (TREE_CODE (type
) != RECORD_TYPE
)
9490 item
= build1 (code
, type
, node
);
9493 node
= ffecom_stabilize_aggregate_ (node
);
9494 realtype
= TREE_TYPE (TYPE_FIELDS (type
));
9496 ffecom_2 (COMPLEX_EXPR
, type
,
9497 ffecom_1 (NEGATE_EXPR
, realtype
,
9498 ffecom_1 (REALPART_EXPR
, realtype
,
9500 ffecom_1 (NEGATE_EXPR
, realtype
,
9501 ffecom_1 (IMAGPART_EXPR
, realtype
,
9506 item
= build1 (code
, type
, node
);
9510 if (TREE_SIDE_EFFECTS (node
))
9511 TREE_SIDE_EFFECTS (item
) = 1;
9512 if (code
== ADDR_EXPR
&& staticp (node
))
9513 TREE_CONSTANT (item
) = 1;
9514 else if (code
== INDIRECT_REF
)
9515 TREE_READONLY (item
) = TYPE_READONLY (type
);
9519 /* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except
9520 handles TREE_CODE (node) == FUNCTION_DECL. In particular,
9521 does not set TREE_ADDRESSABLE (because calling an inline
9522 function does not mean the function needs to be separately
9526 ffecom_1_fn (tree node
)
9531 if (node
== error_mark_node
)
9532 return error_mark_node
;
9534 type
= build_type_variant (TREE_TYPE (node
),
9535 TREE_READONLY (node
),
9536 TREE_THIS_VOLATILE (node
));
9537 item
= build1 (ADDR_EXPR
,
9538 build_pointer_type (type
), node
);
9539 if (TREE_SIDE_EFFECTS (node
))
9540 TREE_SIDE_EFFECTS (item
) = 1;
9542 TREE_CONSTANT (item
) = 1;
9546 /* Essentially does a "fold (build (code, type, node1, node2))" while
9547 checking for certain housekeeping things. */
9550 ffecom_2 (enum tree_code code
, tree type
, tree node1
,
9555 if ((node1
== error_mark_node
)
9556 || (node2
== error_mark_node
)
9557 || (type
== error_mark_node
))
9558 return error_mark_node
;
9560 switch (ffe_is_emulate_complex () ? code
: NOP_EXPR
)
9562 tree a
, b
, c
, d
, realtype
;
9565 assert ("no CONJ_EXPR support yet" == NULL
);
9566 return error_mark_node
;
9569 item
= build_tree_list (TYPE_FIELDS (type
), node1
);
9570 TREE_CHAIN (item
) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type
)), node2
);
9571 item
= build_constructor (type
, item
);
9575 if (TREE_CODE (type
) != RECORD_TYPE
)
9577 item
= build (code
, type
, node1
, node2
);
9580 node1
= ffecom_stabilize_aggregate_ (node1
);
9581 node2
= ffecom_stabilize_aggregate_ (node2
);
9582 realtype
= TREE_TYPE (TYPE_FIELDS (type
));
9584 ffecom_2 (COMPLEX_EXPR
, type
,
9585 ffecom_2 (PLUS_EXPR
, realtype
,
9586 ffecom_1 (REALPART_EXPR
, realtype
,
9588 ffecom_1 (REALPART_EXPR
, realtype
,
9590 ffecom_2 (PLUS_EXPR
, realtype
,
9591 ffecom_1 (IMAGPART_EXPR
, realtype
,
9593 ffecom_1 (IMAGPART_EXPR
, realtype
,
9598 if (TREE_CODE (type
) != RECORD_TYPE
)
9600 item
= build (code
, type
, node1
, node2
);
9603 node1
= ffecom_stabilize_aggregate_ (node1
);
9604 node2
= ffecom_stabilize_aggregate_ (node2
);
9605 realtype
= TREE_TYPE (TYPE_FIELDS (type
));
9607 ffecom_2 (COMPLEX_EXPR
, type
,
9608 ffecom_2 (MINUS_EXPR
, realtype
,
9609 ffecom_1 (REALPART_EXPR
, realtype
,
9611 ffecom_1 (REALPART_EXPR
, realtype
,
9613 ffecom_2 (MINUS_EXPR
, realtype
,
9614 ffecom_1 (IMAGPART_EXPR
, realtype
,
9616 ffecom_1 (IMAGPART_EXPR
, realtype
,
9621 if (TREE_CODE (type
) != RECORD_TYPE
)
9623 item
= build (code
, type
, node1
, node2
);
9626 node1
= ffecom_stabilize_aggregate_ (node1
);
9627 node2
= ffecom_stabilize_aggregate_ (node2
);
9628 realtype
= TREE_TYPE (TYPE_FIELDS (type
));
9629 a
= save_expr (ffecom_1 (REALPART_EXPR
, realtype
,
9631 b
= save_expr (ffecom_1 (IMAGPART_EXPR
, realtype
,
9633 c
= save_expr (ffecom_1 (REALPART_EXPR
, realtype
,
9635 d
= save_expr (ffecom_1 (IMAGPART_EXPR
, realtype
,
9638 ffecom_2 (COMPLEX_EXPR
, type
,
9639 ffecom_2 (MINUS_EXPR
, realtype
,
9640 ffecom_2 (MULT_EXPR
, realtype
,
9643 ffecom_2 (MULT_EXPR
, realtype
,
9646 ffecom_2 (PLUS_EXPR
, realtype
,
9647 ffecom_2 (MULT_EXPR
, realtype
,
9650 ffecom_2 (MULT_EXPR
, realtype
,
9656 if ((TREE_CODE (node1
) != RECORD_TYPE
)
9657 && (TREE_CODE (node2
) != RECORD_TYPE
))
9659 item
= build (code
, type
, node1
, node2
);
9662 assert (TREE_CODE (node1
) == RECORD_TYPE
);
9663 assert (TREE_CODE (node2
) == RECORD_TYPE
);
9664 node1
= ffecom_stabilize_aggregate_ (node1
);
9665 node2
= ffecom_stabilize_aggregate_ (node2
);
9666 realtype
= TREE_TYPE (TYPE_FIELDS (type
));
9668 ffecom_2 (TRUTH_ANDIF_EXPR
, type
,
9669 ffecom_2 (code
, type
,
9670 ffecom_1 (REALPART_EXPR
, realtype
,
9672 ffecom_1 (REALPART_EXPR
, realtype
,
9674 ffecom_2 (code
, type
,
9675 ffecom_1 (IMAGPART_EXPR
, realtype
,
9677 ffecom_1 (IMAGPART_EXPR
, realtype
,
9682 if ((TREE_CODE (node1
) != RECORD_TYPE
)
9683 && (TREE_CODE (node2
) != RECORD_TYPE
))
9685 item
= build (code
, type
, node1
, node2
);
9688 assert (TREE_CODE (node1
) == RECORD_TYPE
);
9689 assert (TREE_CODE (node2
) == RECORD_TYPE
);
9690 node1
= ffecom_stabilize_aggregate_ (node1
);
9691 node2
= ffecom_stabilize_aggregate_ (node2
);
9692 realtype
= TREE_TYPE (TYPE_FIELDS (type
));
9694 ffecom_2 (TRUTH_ORIF_EXPR
, type
,
9695 ffecom_2 (code
, type
,
9696 ffecom_1 (REALPART_EXPR
, realtype
,
9698 ffecom_1 (REALPART_EXPR
, realtype
,
9700 ffecom_2 (code
, type
,
9701 ffecom_1 (IMAGPART_EXPR
, realtype
,
9703 ffecom_1 (IMAGPART_EXPR
, realtype
,
9708 item
= build (code
, type
, node1
, node2
);
9712 if (TREE_SIDE_EFFECTS (node1
) || TREE_SIDE_EFFECTS (node2
))
9713 TREE_SIDE_EFFECTS (item
) = 1;
9717 /* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint
9719 ffesymbol s; // the ENTRY point itself
9720 if (ffecom_2pass_advise_entrypoint(s))
9721 // the ENTRY point has been accepted
9723 Does whatever compiler needs to do when it learns about the entrypoint,
9724 like determine the return type of the master function, count the
9725 number of entrypoints, etc. Returns FALSE if the return type is
9726 not compatible with the return type(s) of other entrypoint(s).
9728 NOTE: for every call to this fn that returns TRUE, _do_entrypoint must
9729 later (after _finish_progunit) be called with the same entrypoint(s)
9730 as passed to this fn for which TRUE was returned.
9733 Return FALSE if the return type conflicts with previous entrypoints. */
9736 ffecom_2pass_advise_entrypoint (ffesymbol entry
)
9738 ffebld list
; /* opITEM. */
9739 ffebld mlist
; /* opITEM. */
9740 ffebld plist
; /* opITEM. */
9741 ffebld arg
; /* ffebld_head(opITEM). */
9742 ffebld item
; /* opITEM. */
9743 ffesymbol s
; /* ffebld_symter(arg). */
9744 ffeinfoBasictype bt
= ffesymbol_basictype (entry
);
9745 ffeinfoKindtype kt
= ffesymbol_kindtype (entry
);
9746 ffetargetCharacterSize size
= ffesymbol_size (entry
);
9749 if (ffecom_num_entrypoints_
== 0)
9750 { /* First entrypoint, make list of main
9751 arglist's dummies. */
9752 assert (ffecom_primary_entry_
!= NULL
);
9754 ffecom_master_bt_
= ffesymbol_basictype (ffecom_primary_entry_
);
9755 ffecom_master_kt_
= ffesymbol_kindtype (ffecom_primary_entry_
);
9756 ffecom_master_size_
= ffesymbol_size (ffecom_primary_entry_
);
9758 for (plist
= NULL
, list
= ffesymbol_dummyargs (ffecom_primary_entry_
);
9760 list
= ffebld_trail (list
))
9762 arg
= ffebld_head (list
);
9763 if (ffebld_op (arg
) != FFEBLD_opSYMTER
)
9764 continue; /* Alternate return or some such thing. */
9765 item
= ffebld_new_item (arg
, NULL
);
9767 ffecom_master_arglist_
= item
;
9769 ffebld_set_trail (plist
, item
);
9774 /* If necessary, scan entry arglist for alternate returns. Do this scan
9775 apparently redundantly (it's done below to UNIONize the arglists) so
9776 that we don't complain about RETURN 1 if an offending ENTRY is the only
9777 one with an alternate return. */
9779 if (!ffecom_is_altreturning_
)
9781 for (list
= ffesymbol_dummyargs (entry
);
9783 list
= ffebld_trail (list
))
9785 arg
= ffebld_head (list
);
9786 if (ffebld_op (arg
) == FFEBLD_opSTAR
)
9788 ffecom_is_altreturning_
= TRUE
;
9794 /* Now check type compatibility. */
9796 switch (ffecom_master_bt_
)
9798 case FFEINFO_basictypeNONE
:
9799 ok
= (bt
!= FFEINFO_basictypeCHARACTER
);
9802 case FFEINFO_basictypeCHARACTER
:
9804 = (bt
== FFEINFO_basictypeCHARACTER
)
9805 && (kt
== ffecom_master_kt_
)
9806 && (size
== ffecom_master_size_
);
9809 case FFEINFO_basictypeANY
:
9810 return FALSE
; /* Just don't bother. */
9813 if (bt
== FFEINFO_basictypeCHARACTER
)
9819 if ((bt
!= ffecom_master_bt_
) || (kt
!= ffecom_master_kt_
))
9821 ffecom_master_bt_
= FFEINFO_basictypeNONE
;
9822 ffecom_master_kt_
= FFEINFO_kindtypeNONE
;
9829 ffebad_start (FFEBAD_ENTRY_CONFLICTS
);
9830 ffest_ffebad_here_current_stmt (0);
9832 return FALSE
; /* Can't handle entrypoint. */
9835 /* Entrypoint type compatible with previous types. */
9837 ++ffecom_num_entrypoints_
;
9839 /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */
9841 for (list
= ffesymbol_dummyargs (entry
);
9843 list
= ffebld_trail (list
))
9845 arg
= ffebld_head (list
);
9846 if (ffebld_op (arg
) != FFEBLD_opSYMTER
)
9847 continue; /* Alternate return or some such thing. */
9848 s
= ffebld_symter (arg
);
9849 for (plist
= NULL
, mlist
= ffecom_master_arglist_
;
9851 plist
= mlist
, mlist
= ffebld_trail (mlist
))
9852 { /* plist points to previous item for easy
9853 appending of arg. */
9854 if (ffebld_symter (ffebld_head (mlist
)) == s
)
9855 break; /* Already have this arg in the master list. */
9858 continue; /* Already have this arg in the master list. */
9860 /* Append this arg to the master list. */
9862 item
= ffebld_new_item (arg
, NULL
);
9864 ffecom_master_arglist_
= item
;
9866 ffebld_set_trail (plist
, item
);
9872 /* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint
9874 ffesymbol s; // the ENTRY point itself
9875 ffecom_2pass_do_entrypoint(s);
9877 Does whatever compiler needs to do to make the entrypoint actually
9878 happen. Must be called for each entrypoint after
9879 ffecom_finish_progunit is called. */
9882 ffecom_2pass_do_entrypoint (ffesymbol entry
)
9884 static int mfn_num
= 0;
9887 if (mfn_num
!= ffecom_num_fns_
)
9888 { /* First entrypoint for this program unit. */
9890 mfn_num
= ffecom_num_fns_
;
9891 ffecom_do_entry_ (ffecom_primary_entry_
, 0);
9896 --ffecom_num_entrypoints_
;
9898 ffecom_do_entry_ (entry
, ent_num
);
9901 /* Essentially does a "fold (build (code, type, node1, node2))" while
9902 checking for certain housekeeping things. Always sets
9903 TREE_SIDE_EFFECTS. */
9906 ffecom_2s (enum tree_code code
, tree type
, tree node1
,
9911 if ((node1
== error_mark_node
)
9912 || (node2
== error_mark_node
)
9913 || (type
== error_mark_node
))
9914 return error_mark_node
;
9916 item
= build (code
, type
, node1
, node2
);
9917 TREE_SIDE_EFFECTS (item
) = 1;
9921 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
9922 checking for certain housekeeping things. */
9925 ffecom_3 (enum tree_code code
, tree type
, tree node1
,
9926 tree node2
, tree node3
)
9930 if ((node1
== error_mark_node
)
9931 || (node2
== error_mark_node
)
9932 || (node3
== error_mark_node
)
9933 || (type
== error_mark_node
))
9934 return error_mark_node
;
9936 item
= build (code
, type
, node1
, node2
, node3
);
9937 if (TREE_SIDE_EFFECTS (node1
) || TREE_SIDE_EFFECTS (node2
)
9938 || (node3
!= NULL_TREE
&& TREE_SIDE_EFFECTS (node3
)))
9939 TREE_SIDE_EFFECTS (item
) = 1;
9943 /* Essentially does a "fold (build (code, type, node1, node2, node3))" while
9944 checking for certain housekeeping things. Always sets
9945 TREE_SIDE_EFFECTS. */
9948 ffecom_3s (enum tree_code code
, tree type
, tree node1
,
9949 tree node2
, tree node3
)
9953 if ((node1
== error_mark_node
)
9954 || (node2
== error_mark_node
)
9955 || (node3
== error_mark_node
)
9956 || (type
== error_mark_node
))
9957 return error_mark_node
;
9959 item
= build (code
, type
, node1
, node2
, node3
);
9960 TREE_SIDE_EFFECTS (item
) = 1;
9964 /* ffecom_arg_expr -- Transform argument expr into gcc tree
9966 See use by ffecom_list_expr.
9968 If expression is NULL, returns an integer zero tree. If it is not
9969 a CHARACTER expression, returns whatever ffecom_expr
9970 returns and sets the length return value to NULL_TREE. Otherwise
9971 generates code to evaluate the character expression, returns the proper
9972 pointer to the result, but does NOT set the length return value to a tree
9973 that specifies the length of the result. (In other words, the length
9974 variable is always set to NULL_TREE, because a length is never passed.)
9977 Don't set returned length, since nobody needs it (yet; someday if
9978 we allow CHARACTER*(*) dummies to statement functions, we'll need
9982 ffecom_arg_expr (ffebld expr
, tree
*length
)
9986 *length
= NULL_TREE
;
9989 return integer_zero_node
;
9991 if (ffeinfo_basictype (ffebld_info (expr
)) != FFEINFO_basictypeCHARACTER
)
9992 return ffecom_expr (expr
);
9994 return ffecom_arg_ptr_to_expr (expr
, &ign
);
9997 /* Transform expression into constant argument-pointer-to-expression tree.
9999 If the expression can be transformed into a argument-pointer-to-expression
10000 tree that is constant, that is done, and the tree returned. Else
10001 NULL_TREE is returned.
10003 That way, a caller can attempt to provide compile-time initialization
10004 of a variable and, if that fails, *then* choose to start a new block
10005 and resort to using temporaries, as appropriate. */
10008 ffecom_arg_ptr_to_const_expr (ffebld expr
, tree
*length
)
10011 return integer_zero_node
;
10013 if (ffebld_op (expr
) == FFEBLD_opANY
)
10016 *length
= error_mark_node
;
10017 return error_mark_node
;
10020 if (ffebld_arity (expr
) == 0
10021 && (ffebld_op (expr
) != FFEBLD_opSYMTER
10022 || ffebld_where (expr
) == FFEINFO_whereCOMMON
10023 || ffebld_where (expr
) == FFEINFO_whereGLOBAL
10024 || ffebld_where (expr
) == FFEINFO_whereINTRINSIC
))
10028 t
= ffecom_arg_ptr_to_expr (expr
, length
);
10029 assert (TREE_CONSTANT (t
));
10030 assert (! length
|| TREE_CONSTANT (*length
));
10035 && ffebld_size (expr
) != FFETARGET_charactersizeNONE
)
10036 *length
= build_int_2 (ffebld_size (expr
), 0);
10038 *length
= NULL_TREE
;
10042 /* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree
10044 See use by ffecom_list_ptr_to_expr.
10046 If expression is NULL, returns an integer zero tree. If it is not
10047 a CHARACTER expression, returns whatever ffecom_ptr_to_expr
10048 returns and sets the length return value to NULL_TREE. Otherwise
10049 generates code to evaluate the character expression, returns the proper
10050 pointer to the result, AND sets the length return value to a tree that
10051 specifies the length of the result.
10053 If the length argument is NULL, this is a slightly special
10054 case of building a FORMAT expression, that is, an expression that
10055 will be used at run time without regard to length. For the current
10056 implementation, which uses the libf2c library, this means it is nice
10057 to append a null byte to the end of the expression, where feasible,
10058 to make sure any diagnostic about the FORMAT string terminates at
10061 For now, treat %REF(char-expr) as the same as char-expr with a NULL
10062 length argument. This might even be seen as a feature, if a null
10063 byte can always be appended. */
10066 ffecom_arg_ptr_to_expr (ffebld expr
, tree
*length
)
10070 ffecomConcatList_ catlist
;
10072 if (length
!= NULL
)
10073 *length
= NULL_TREE
;
10076 return integer_zero_node
;
10078 switch (ffebld_op (expr
))
10080 case FFEBLD_opPERCENT_VAL
:
10081 if (ffeinfo_basictype (ffebld_info (expr
)) != FFEINFO_basictypeCHARACTER
)
10082 return ffecom_expr (ffebld_left (expr
));
10087 temp_exp
= ffecom_arg_ptr_to_expr (ffebld_left (expr
), &temp_length
);
10088 if (temp_exp
== error_mark_node
)
10089 return error_mark_node
;
10091 return ffecom_1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (temp_exp
)),
10095 case FFEBLD_opPERCENT_REF
:
10096 if (ffeinfo_basictype (ffebld_info (expr
)) != FFEINFO_basictypeCHARACTER
)
10097 return ffecom_ptr_to_expr (ffebld_left (expr
));
10098 if (length
!= NULL
)
10100 ign_length
= NULL_TREE
;
10101 length
= &ign_length
;
10103 expr
= ffebld_left (expr
);
10106 case FFEBLD_opPERCENT_DESCR
:
10107 switch (ffeinfo_basictype (ffebld_info (expr
)))
10109 case FFEINFO_basictypeCHARACTER
:
10110 break; /* Passed by descriptor anyway. */
10113 item
= ffecom_ptr_to_expr (expr
);
10114 if (item
!= error_mark_node
)
10115 *length
= TYPE_SIZE (TREE_TYPE (TREE_TYPE (item
)));
10124 if (ffeinfo_basictype (ffebld_info (expr
)) != FFEINFO_basictypeCHARACTER
)
10125 return ffecom_ptr_to_expr (expr
);
10127 assert (ffeinfo_kindtype (ffebld_info (expr
))
10128 == FFEINFO_kindtypeCHARACTER1
);
10130 while (ffebld_op (expr
) == FFEBLD_opPAREN
)
10131 expr
= ffebld_left (expr
);
10133 catlist
= ffecom_concat_list_new_ (expr
, FFETARGET_charactersizeNONE
);
10134 switch (ffecom_concat_list_count_ (catlist
))
10136 case 0: /* Shouldn't happen, but in case it does... */
10137 if (length
!= NULL
)
10139 *length
= ffecom_f2c_ftnlen_zero_node
;
10140 TREE_TYPE (*length
) = ffecom_f2c_ftnlen_type_node
;
10142 ffecom_concat_list_kill_ (catlist
);
10143 return null_pointer_node
;
10145 case 1: /* The (fairly) easy case. */
10146 if (length
== NULL
)
10147 ffecom_char_args_with_null_ (&item
, &ign_length
,
10148 ffecom_concat_list_expr_ (catlist
, 0));
10150 ffecom_char_args_ (&item
, length
,
10151 ffecom_concat_list_expr_ (catlist
, 0));
10152 ffecom_concat_list_kill_ (catlist
);
10153 assert (item
!= NULL_TREE
);
10156 default: /* Must actually concatenate things. */
10161 int count
= ffecom_concat_list_count_ (catlist
);
10172 ffetargetCharacterSize sz
;
10174 sz
= ffecom_concat_list_maxlen_ (catlist
);
10176 assert (sz
!= FFETARGET_charactersizeNONE
);
10181 hook
= ffebld_nonter_hook (expr
);
10183 assert (TREE_CODE (hook
) == TREE_VEC
);
10184 assert (TREE_VEC_LENGTH (hook
) == 3);
10185 length_array
= lengths
= TREE_VEC_ELT (hook
, 0);
10186 item_array
= items
= TREE_VEC_ELT (hook
, 1);
10187 temporary
= TREE_VEC_ELT (hook
, 2);
10190 known_length
= ffecom_f2c_ftnlen_zero_node
;
10192 for (i
= 0; i
< count
; ++i
)
10195 && (length
== NULL
))
10196 ffecom_char_args_with_null_ (&citem
, &clength
,
10197 ffecom_concat_list_expr_ (catlist
, i
));
10199 ffecom_char_args_ (&citem
, &clength
,
10200 ffecom_concat_list_expr_ (catlist
, i
));
10201 if ((citem
== error_mark_node
)
10202 || (clength
== error_mark_node
))
10204 ffecom_concat_list_kill_ (catlist
);
10205 *length
= error_mark_node
;
10206 return error_mark_node
;
10210 = ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (items
),
10211 ffecom_modify (void_type_node
,
10212 ffecom_2 (ARRAY_REF
,
10213 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array
))),
10215 build_int_2 (i
, 0)),
10218 clength
= ffecom_save_tree (clength
);
10219 if (length
!= NULL
)
10221 = ffecom_2 (PLUS_EXPR
, ffecom_f2c_ftnlen_type_node
,
10225 = ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (lengths
),
10226 ffecom_modify (void_type_node
,
10227 ffecom_2 (ARRAY_REF
,
10228 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array
))),
10230 build_int_2 (i
, 0)),
10235 temporary
= ffecom_1 (ADDR_EXPR
,
10236 build_pointer_type (TREE_TYPE (temporary
)),
10239 item
= build_tree_list (NULL_TREE
, temporary
);
10241 = build_tree_list (NULL_TREE
,
10242 ffecom_1 (ADDR_EXPR
,
10243 build_pointer_type (TREE_TYPE (items
)),
10245 TREE_CHAIN (TREE_CHAIN (item
))
10246 = build_tree_list (NULL_TREE
,
10247 ffecom_1 (ADDR_EXPR
,
10248 build_pointer_type (TREE_TYPE (lengths
)),
10250 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item
)))
10253 ffecom_1 (ADDR_EXPR
, ffecom_f2c_ptr_to_ftnlen_type_node
,
10254 convert (ffecom_f2c_ftnlen_type_node
,
10255 build_int_2 (count
, 0))));
10256 num
= build_int_2 (sz
, 0);
10257 TREE_TYPE (num
) = ffecom_f2c_ftnlen_type_node
;
10258 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item
))))
10259 = build_tree_list (NULL_TREE
, num
);
10261 item
= ffecom_call_gfrt (FFECOM_gfrtCAT
, item
, NULL_TREE
);
10262 TREE_SIDE_EFFECTS (item
) = 1;
10263 item
= ffecom_2 (COMPOUND_EXPR
, TREE_TYPE (temporary
),
10267 if (length
!= NULL
)
10268 *length
= known_length
;
10271 ffecom_concat_list_kill_ (catlist
);
10272 assert (item
!= NULL_TREE
);
10276 /* Generate call to run-time function.
10278 The first arg is the GNU Fortran Run-Time function index, the second
10279 arg is the list of arguments to pass to it. Returned is the expression
10280 (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the
10281 result (which may be void). */
10284 ffecom_call_gfrt (ffecomGfrt ix
, tree args
, tree hook
)
10286 return ffecom_call_ (ffecom_gfrt_tree_ (ix
),
10287 ffecom_gfrt_kindtype (ix
),
10288 ffe_is_f2c_library () && ffecom_gfrt_complex_
[ix
],
10289 NULL_TREE
, args
, NULL_TREE
, NULL
,
10290 NULL
, NULL_TREE
, TRUE
, hook
);
10293 /* Transform constant-union to tree. */
10296 ffecom_constantunion (ffebldConstantUnion
*cu
, ffeinfoBasictype bt
,
10297 ffeinfoKindtype kt
, tree tree_type
)
10303 case FFEINFO_basictypeINTEGER
:
10305 HOST_WIDE_INT hi
, lo
;
10309 #if FFETARGET_okINTEGER1
10310 case FFEINFO_kindtypeINTEGER1
:
10311 lo
= ffebld_cu_val_integer1 (*cu
);
10312 hi
= (lo
< 0) ? -1 : 0;
10316 #if FFETARGET_okINTEGER2
10317 case FFEINFO_kindtypeINTEGER2
:
10318 lo
= ffebld_cu_val_integer2 (*cu
);
10319 hi
= (lo
< 0) ? -1 : 0;
10323 #if FFETARGET_okINTEGER3
10324 case FFEINFO_kindtypeINTEGER3
:
10325 lo
= ffebld_cu_val_integer3 (*cu
);
10326 hi
= (lo
< 0) ? -1 : 0;
10330 #if FFETARGET_okINTEGER4
10331 case FFEINFO_kindtypeINTEGER4
:
10332 #if HOST_BITS_PER_LONGLONG > HOST_BITS_PER_WIDE_INT
10334 long long int big
= ffebld_cu_val_integer4 (*cu
);
10335 hi
= (HOST_WIDE_INT
) (big
>> HOST_BITS_PER_WIDE_INT
);
10336 lo
= (HOST_WIDE_INT
) big
;
10339 lo
= ffebld_cu_val_integer4 (*cu
);
10340 hi
= (lo
< 0) ? -1 : 0;
10346 assert ("bad INTEGER constant kind type" == NULL
);
10347 /* Fall through. */
10348 case FFEINFO_kindtypeANY
:
10349 return error_mark_node
;
10351 item
= build_int_2 (lo
, hi
);
10352 TREE_TYPE (item
) = tree_type
;
10356 case FFEINFO_basictypeLOGICAL
:
10362 #if FFETARGET_okLOGICAL1
10363 case FFEINFO_kindtypeLOGICAL1
:
10364 val
= ffebld_cu_val_logical1 (*cu
);
10368 #if FFETARGET_okLOGICAL2
10369 case FFEINFO_kindtypeLOGICAL2
:
10370 val
= ffebld_cu_val_logical2 (*cu
);
10374 #if FFETARGET_okLOGICAL3
10375 case FFEINFO_kindtypeLOGICAL3
:
10376 val
= ffebld_cu_val_logical3 (*cu
);
10380 #if FFETARGET_okLOGICAL4
10381 case FFEINFO_kindtypeLOGICAL4
:
10382 val
= ffebld_cu_val_logical4 (*cu
);
10387 assert ("bad LOGICAL constant kind type" == NULL
);
10388 /* Fall through. */
10389 case FFEINFO_kindtypeANY
:
10390 return error_mark_node
;
10392 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10393 TREE_TYPE (item
) = tree_type
;
10397 case FFEINFO_basictypeREAL
:
10399 REAL_VALUE_TYPE val
;
10403 #if FFETARGET_okREAL1
10404 case FFEINFO_kindtypeREAL1
:
10405 val
= ffetarget_value_real1 (ffebld_cu_val_real1 (*cu
));
10409 #if FFETARGET_okREAL2
10410 case FFEINFO_kindtypeREAL2
:
10411 val
= ffetarget_value_real2 (ffebld_cu_val_real2 (*cu
));
10415 #if FFETARGET_okREAL3
10416 case FFEINFO_kindtypeREAL3
:
10417 val
= ffetarget_value_real3 (ffebld_cu_val_real3 (*cu
));
10422 assert ("bad REAL constant kind type" == NULL
);
10423 /* Fall through. */
10424 case FFEINFO_kindtypeANY
:
10425 return error_mark_node
;
10427 item
= build_real (tree_type
, val
);
10431 case FFEINFO_basictypeCOMPLEX
:
10433 REAL_VALUE_TYPE real
;
10434 REAL_VALUE_TYPE imag
;
10435 tree el_type
= ffecom_tree_type
[FFEINFO_basictypeREAL
][kt
];
10439 #if FFETARGET_okCOMPLEX1
10440 case FFEINFO_kindtypeREAL1
:
10441 real
= ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu
).real
);
10442 imag
= ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu
).imaginary
);
10446 #if FFETARGET_okCOMPLEX2
10447 case FFEINFO_kindtypeREAL2
:
10448 real
= ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu
).real
);
10449 imag
= ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu
).imaginary
);
10453 #if FFETARGET_okCOMPLEX3
10454 case FFEINFO_kindtypeREAL3
:
10455 real
= ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu
).real
);
10456 imag
= ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu
).imaginary
);
10461 assert ("bad REAL constant kind type" == NULL
);
10462 /* Fall through. */
10463 case FFEINFO_kindtypeANY
:
10464 return error_mark_node
;
10466 item
= ffecom_build_complex_constant_ (tree_type
,
10467 build_real (el_type
, real
),
10468 build_real (el_type
, imag
));
10472 case FFEINFO_basictypeCHARACTER
:
10473 { /* Happens only in DATA and similar contexts. */
10474 ffetargetCharacter1 val
;
10478 #if FFETARGET_okCHARACTER1
10479 case FFEINFO_kindtypeLOGICAL1
:
10480 val
= ffebld_cu_val_character1 (*cu
);
10485 assert ("bad CHARACTER constant kind type" == NULL
);
10486 /* Fall through. */
10487 case FFEINFO_kindtypeANY
:
10488 return error_mark_node
;
10490 item
= build_string (ffetarget_length_character1 (val
),
10491 ffetarget_text_character1 (val
));
10493 = build_type_variant (build_array_type (char_type_node
,
10495 (integer_type_node
,
10498 (ffetarget_length_character1
10504 case FFEINFO_basictypeHOLLERITH
:
10506 ffetargetHollerith h
;
10508 h
= ffebld_cu_val_hollerith (*cu
);
10510 /* If not at least as wide as default INTEGER, widen it. */
10511 if (h
.length
>= FLOAT_TYPE_SIZE
/ CHAR_TYPE_SIZE
)
10512 item
= build_string (h
.length
, h
.text
);
10515 char str
[FLOAT_TYPE_SIZE
/ CHAR_TYPE_SIZE
];
10517 memcpy (str
, h
.text
, h
.length
);
10518 memset (&str
[h
.length
], ' ',
10519 FLOAT_TYPE_SIZE
/ CHAR_TYPE_SIZE
10521 item
= build_string (FLOAT_TYPE_SIZE
/ CHAR_TYPE_SIZE
,
10525 = build_type_variant (build_array_type (char_type_node
,
10527 (integer_type_node
,
10535 case FFEINFO_basictypeTYPELESS
:
10537 ffetargetInteger1 ival
;
10538 ffetargetTypeless tless
;
10541 tless
= ffebld_cu_val_typeless (*cu
);
10542 error
= ffetarget_convert_integer1_typeless (&ival
, tless
);
10543 assert (error
== FFEBAD
);
10545 item
= build_int_2 ((int) ival
, 0);
10550 assert ("not yet on constant type" == NULL
);
10551 /* Fall through. */
10552 case FFEINFO_basictypeANY
:
10553 return error_mark_node
;
10556 TREE_CONSTANT (item
) = 1;
10561 /* Transform constant-union to tree, with the type known. */
10564 ffecom_constantunion_with_type (ffebldConstantUnion
*cu
,
10565 tree tree_type
, ffebldConst ct
)
10573 #if FFETARGET_okINTEGER1
10574 case FFEBLD_constINTEGER1
:
10575 val
= ffebld_cu_val_integer1 (*cu
);
10576 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10579 #if FFETARGET_okINTEGER2
10580 case FFEBLD_constINTEGER2
:
10581 val
= ffebld_cu_val_integer2 (*cu
);
10582 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10585 #if FFETARGET_okINTEGER3
10586 case FFEBLD_constINTEGER3
:
10587 val
= ffebld_cu_val_integer3 (*cu
);
10588 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10591 #if FFETARGET_okINTEGER4
10592 case FFEBLD_constINTEGER4
:
10593 #if HOST_BITS_PER_LONGLONG > HOST_BITS_PER_WIDE_INT
10595 long long int big
= ffebld_cu_val_integer4 (*cu
);
10596 item
= build_int_2 ((HOST_WIDE_INT
) big
,
10598 (big
>> HOST_BITS_PER_WIDE_INT
));
10601 val
= ffebld_cu_val_integer4 (*cu
);
10602 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10606 #if FFETARGET_okLOGICAL1
10607 case FFEBLD_constLOGICAL1
:
10608 val
= ffebld_cu_val_logical1 (*cu
);
10609 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10612 #if FFETARGET_okLOGICAL2
10613 case FFEBLD_constLOGICAL2
:
10614 val
= ffebld_cu_val_logical2 (*cu
);
10615 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10618 #if FFETARGET_okLOGICAL3
10619 case FFEBLD_constLOGICAL3
:
10620 val
= ffebld_cu_val_logical3 (*cu
);
10621 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10624 #if FFETARGET_okLOGICAL4
10625 case FFEBLD_constLOGICAL4
:
10626 val
= ffebld_cu_val_logical4 (*cu
);
10627 item
= build_int_2 (val
, (val
< 0) ? -1 : 0);
10631 assert ("constant type not supported"==NULL
);
10632 return error_mark_node
;
10636 TREE_TYPE (item
) = tree_type
;
10638 TREE_CONSTANT (item
) = 1;
10642 /* Transform expression into constant tree.
10644 If the expression can be transformed into a tree that is constant,
10645 that is done, and the tree returned. Else NULL_TREE is returned.
10647 That way, a caller can attempt to provide compile-time initialization
10648 of a variable and, if that fails, *then* choose to start a new block
10649 and resort to using temporaries, as appropriate. */
10652 ffecom_const_expr (ffebld expr
)
10655 return integer_zero_node
;
10657 if (ffebld_op (expr
) == FFEBLD_opANY
)
10658 return error_mark_node
;
10660 if (ffebld_arity (expr
) == 0
10661 && (ffebld_op (expr
) != FFEBLD_opSYMTER
10662 || ffebld_where (expr
) == FFEINFO_whereGLOBAL
10663 || ffebld_where (expr
) == FFEINFO_whereINTRINSIC
))
10667 t
= ffecom_expr (expr
);
10668 assert (TREE_CONSTANT (t
));
10675 /* Handy way to make a field in a struct/union. */
10678 ffecom_decl_field (tree context
, tree prevfield
,
10679 const char *name
, tree type
)
10683 field
= build_decl (FIELD_DECL
, get_identifier (name
), type
);
10684 DECL_CONTEXT (field
) = context
;
10685 DECL_ALIGN (field
) = 0;
10686 DECL_USER_ALIGN (field
) = 0;
10687 if (prevfield
!= NULL_TREE
)
10688 TREE_CHAIN (prevfield
) = field
;
10694 ffecom_close_include (FILE *f
)
10696 ffecom_close_include_ (f
);
10699 /* End a compound statement (block). */
10702 ffecom_end_compstmt (void)
10704 return bison_rule_compstmt_ ();
10707 /* ffecom_end_transition -- Perform end transition on all symbols
10709 ffecom_end_transition();
10711 Calls ffecom_sym_end_transition for each global and local symbol. */
10714 ffecom_end_transition ()
10718 if (ffe_is_ffedebug ())
10719 fprintf (dmpout
, "; end_stmt_transition\n");
10721 ffecom_list_blockdata_
= NULL
;
10722 ffecom_list_common_
= NULL
;
10724 ffesymbol_drive (ffecom_sym_end_transition
);
10725 if (ffe_is_ffedebug ())
10727 ffestorag_report ();
10730 ffecom_start_progunit_ ();
10732 for (item
= ffecom_list_blockdata_
;
10734 item
= ffebld_trail (item
))
10741 static int number
= 0;
10743 callee
= ffebld_head (item
);
10744 s
= ffebld_symter (callee
);
10745 t
= ffesymbol_hook (s
).decl_tree
;
10746 if (t
== NULL_TREE
)
10748 s
= ffecom_sym_transform_ (s
);
10749 t
= ffesymbol_hook (s
).decl_tree
;
10752 dt
= build_pointer_type (TREE_TYPE (t
));
10754 var
= build_decl (VAR_DECL
,
10755 ffecom_get_invented_identifier ("__g77_forceload_%d",
10758 DECL_EXTERNAL (var
) = 0;
10759 TREE_STATIC (var
) = 1;
10760 TREE_PUBLIC (var
) = 0;
10761 DECL_INITIAL (var
) = error_mark_node
;
10762 TREE_USED (var
) = 1;
10764 var
= start_decl (var
, FALSE
);
10766 t
= ffecom_1 (ADDR_EXPR
, dt
, t
);
10768 finish_decl (var
, t
, FALSE
);
10771 /* This handles any COMMON areas that weren't referenced but have, for
10772 example, important initial data. */
10774 for (item
= ffecom_list_common_
;
10776 item
= ffebld_trail (item
))
10777 ffecom_transform_common_ (ffebld_symter (ffebld_head (item
)));
10779 ffecom_list_common_
= NULL
;
10782 /* ffecom_exec_transition -- Perform exec transition on all symbols
10784 ffecom_exec_transition();
10786 Calls ffecom_sym_exec_transition for each global and local symbol.
10787 Make sure error updating not inhibited. */
10790 ffecom_exec_transition ()
10794 if (ffe_is_ffedebug ())
10795 fprintf (dmpout
, "; exec_stmt_transition\n");
10797 inhibited
= ffebad_inhibit ();
10798 ffebad_set_inhibit (FALSE
);
10800 ffesymbol_drive (ffecom_sym_exec_transition
); /* Don't retract! */
10801 ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */
10802 if (ffe_is_ffedebug ())
10804 ffestorag_report ();
10808 ffebad_set_inhibit (TRUE
);
10811 /* Handle assignment statement.
10813 Convert dest and source using ffecom_expr, then join them
10814 with an ASSIGN op and pass the whole thing to expand_expr_stmt. */
10817 ffecom_expand_let_stmt (ffebld dest
, ffebld source
)
10824 if (ffeinfo_basictype (ffebld_info (dest
)) != FFEINFO_basictypeCHARACTER
)
10829 /* This attempts to replicate the test below, but must not be
10830 true when the test below is false. (Always err on the side
10831 of creating unused temporaries, to avoid ICEs.) */
10832 if (ffebld_op (dest
) != FFEBLD_opSYMTER
10833 || ((dest_tree
= ffesymbol_hook (ffebld_symter (dest
)).decl_tree
)
10834 && (TREE_CODE (dest_tree
) != VAR_DECL
10835 || TREE_ADDRESSABLE (dest_tree
))))
10837 ffecom_prepare_expr_ (source
, dest
);
10842 ffecom_prepare_expr_ (source
, NULL
);
10846 ffecom_prepare_expr_w (NULL_TREE
, dest
);
10848 /* For COMPLEX assignment like C1=C2, if partial overlap is possible,
10849 create a temporary through which the assignment is to take place,
10850 since MODIFY_EXPR doesn't handle partial overlap properly. */
10851 if (ffebld_basictype (dest
) == FFEINFO_basictypeCOMPLEX
10852 && ffecom_possible_partial_overlap_ (dest
, source
))
10854 assign_temp
= ffecom_make_tempvar ("complex_let",
10856 [ffebld_basictype (dest
)]
10857 [ffebld_kindtype (dest
)],
10858 FFETARGET_charactersizeNONE
,
10862 assign_temp
= NULL_TREE
;
10864 ffecom_prepare_end ();
10866 dest_tree
= ffecom_expr_w (NULL_TREE
, dest
);
10867 if (dest_tree
== error_mark_node
)
10870 if ((TREE_CODE (dest_tree
) != VAR_DECL
)
10871 || TREE_ADDRESSABLE (dest_tree
))
10872 source_tree
= ffecom_expr_ (source
, dest_tree
, dest
, &dest_used
,
10876 assert (! dest_used
);
10878 source_tree
= ffecom_expr (source
);
10880 if (source_tree
== error_mark_node
)
10884 expr_tree
= source_tree
;
10885 else if (assign_temp
)
10887 expr_tree
= ffecom_2s (MODIFY_EXPR
, void_type_node
,
10890 expand_expr_stmt (expr_tree
);
10891 expr_tree
= ffecom_2s (MODIFY_EXPR
, void_type_node
,
10896 expr_tree
= ffecom_2s (MODIFY_EXPR
, void_type_node
,
10900 expand_expr_stmt (expr_tree
);
10904 ffecom_prepare_let_char_ (ffebld_size_known (dest
), source
);
10905 ffecom_prepare_expr_w (NULL_TREE
, dest
);
10907 ffecom_prepare_end ();
10909 ffecom_char_args_ (&dest_tree
, &dest_length
, dest
);
10910 ffecom_let_char_ (dest_tree
, dest_length
, ffebld_size_known (dest
),
10914 /* ffecom_expr -- Transform expr into gcc tree
10917 ffebld expr; // FFE expression.
10918 tree = ffecom_expr(expr);
10920 Recursive descent on expr while making corresponding tree nodes and
10921 attaching type info and such. */
10924 ffecom_expr (ffebld expr
)
10926 return ffecom_expr_ (expr
, NULL_TREE
, NULL
, NULL
, FALSE
, FALSE
);
10929 /* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */
10932 ffecom_expr_assign (ffebld expr
)
10934 return ffecom_expr_ (expr
, NULL_TREE
, NULL
, NULL
, TRUE
, FALSE
);
10937 /* Like ffecom_expr_rw, but return tree usable for ASSIGN. */
10940 ffecom_expr_assign_w (ffebld expr
)
10942 return ffecom_expr_ (expr
, NULL_TREE
, NULL
, NULL
, TRUE
, FALSE
);
10945 /* Transform expr for use as into read/write tree and stabilize the
10946 reference. Not for use on CHARACTER expressions.
10948 Recursive descent on expr while making corresponding tree nodes and
10949 attaching type info and such. */
10952 ffecom_expr_rw (tree type
, ffebld expr
)
10954 assert (expr
!= NULL
);
10955 /* Different target types not yet supported. */
10956 assert (type
== NULL_TREE
|| type
== ffecom_type_expr (expr
));
10958 return stabilize_reference (ffecom_expr (expr
));
10961 /* Transform expr for use as into write tree and stabilize the
10962 reference. Not for use on CHARACTER expressions.
10964 Recursive descent on expr while making corresponding tree nodes and
10965 attaching type info and such. */
10968 ffecom_expr_w (tree type
, ffebld expr
)
10970 assert (expr
!= NULL
);
10971 /* Different target types not yet supported. */
10972 assert (type
== NULL_TREE
|| type
== ffecom_type_expr (expr
));
10974 return stabilize_reference (ffecom_expr (expr
));
10977 /* Do global stuff. */
10980 ffecom_finish_compile ()
10982 assert (ffecom_outer_function_decl_
== NULL_TREE
);
10983 assert (current_function_decl
== NULL_TREE
);
10985 ffeglobal_drive (ffecom_finish_global_
);
10988 /* Public entry point for front end to access finish_decl. */
10991 ffecom_finish_decl (tree decl
, tree init
, bool is_top_level
)
10993 assert (!is_top_level
);
10994 finish_decl (decl
, init
, FALSE
);
10997 /* Finish a program unit. */
11000 ffecom_finish_progunit ()
11002 ffecom_end_compstmt ();
11004 ffecom_previous_function_decl_
= current_function_decl
;
11005 ffecom_which_entrypoint_decl_
= NULL_TREE
;
11007 finish_function (0);
11010 /* Wrapper for get_identifier. pattern is sprintf-like. */
11013 ffecom_get_invented_identifier (const char *pattern
, ...)
11019 va_start (ap
, pattern
);
11020 if (vasprintf (&nam
, pattern
, ap
) == 0)
11023 decl
= get_identifier (nam
);
11025 IDENTIFIER_INVENTED (decl
) = 1;
11030 ffecom_gfrt_basictype (ffecomGfrt gfrt
)
11032 assert (gfrt
< FFECOM_gfrt
);
11034 switch (ffecom_gfrt_type_
[gfrt
])
11036 case FFECOM_rttypeVOID_
:
11037 case FFECOM_rttypeVOIDSTAR_
:
11038 return FFEINFO_basictypeNONE
;
11040 case FFECOM_rttypeFTNINT_
:
11041 return FFEINFO_basictypeINTEGER
;
11043 case FFECOM_rttypeINTEGER_
:
11044 return FFEINFO_basictypeINTEGER
;
11046 case FFECOM_rttypeLONGINT_
:
11047 return FFEINFO_basictypeINTEGER
;
11049 case FFECOM_rttypeLOGICAL_
:
11050 return FFEINFO_basictypeLOGICAL
;
11052 case FFECOM_rttypeREAL_F2C_
:
11053 case FFECOM_rttypeREAL_GNU_
:
11054 return FFEINFO_basictypeREAL
;
11056 case FFECOM_rttypeCOMPLEX_F2C_
:
11057 case FFECOM_rttypeCOMPLEX_GNU_
:
11058 return FFEINFO_basictypeCOMPLEX
;
11060 case FFECOM_rttypeDOUBLE_
:
11061 case FFECOM_rttypeDOUBLEREAL_
:
11062 return FFEINFO_basictypeREAL
;
11064 case FFECOM_rttypeDBLCMPLX_F2C_
:
11065 case FFECOM_rttypeDBLCMPLX_GNU_
:
11066 return FFEINFO_basictypeCOMPLEX
;
11068 case FFECOM_rttypeCHARACTER_
:
11069 return FFEINFO_basictypeCHARACTER
;
11072 return FFEINFO_basictypeANY
;
11077 ffecom_gfrt_kindtype (ffecomGfrt gfrt
)
11079 assert (gfrt
< FFECOM_gfrt
);
11081 switch (ffecom_gfrt_type_
[gfrt
])
11083 case FFECOM_rttypeVOID_
:
11084 case FFECOM_rttypeVOIDSTAR_
:
11085 return FFEINFO_kindtypeNONE
;
11087 case FFECOM_rttypeFTNINT_
:
11088 return FFEINFO_kindtypeINTEGER1
;
11090 case FFECOM_rttypeINTEGER_
:
11091 return FFEINFO_kindtypeINTEGER1
;
11093 case FFECOM_rttypeLONGINT_
:
11094 return FFEINFO_kindtypeINTEGER4
;
11096 case FFECOM_rttypeLOGICAL_
:
11097 return FFEINFO_kindtypeLOGICAL1
;
11099 case FFECOM_rttypeREAL_F2C_
:
11100 case FFECOM_rttypeREAL_GNU_
:
11101 return FFEINFO_kindtypeREAL1
;
11103 case FFECOM_rttypeCOMPLEX_F2C_
:
11104 case FFECOM_rttypeCOMPLEX_GNU_
:
11105 return FFEINFO_kindtypeREAL1
;
11107 case FFECOM_rttypeDOUBLE_
:
11108 case FFECOM_rttypeDOUBLEREAL_
:
11109 return FFEINFO_kindtypeREAL2
;
11111 case FFECOM_rttypeDBLCMPLX_F2C_
:
11112 case FFECOM_rttypeDBLCMPLX_GNU_
:
11113 return FFEINFO_kindtypeREAL2
;
11115 case FFECOM_rttypeCHARACTER_
:
11116 return FFEINFO_kindtypeCHARACTER1
;
11119 return FFEINFO_kindtypeANY
;
11133 tree double_ftype_double
, double_ftype_double_double
;
11134 tree float_ftype_float
, float_ftype_float_float
;
11135 tree ldouble_ftype_ldouble
, ldouble_ftype_ldouble_ldouble
;
11136 tree ffecom_tree_ptr_to_fun_type_void
;
11138 /* This block of code comes from the now-obsolete cktyps.c. It checks
11139 whether the compiler environment is buggy in known ways, some of which
11140 would, if not explicitly checked here, result in subtle bugs in g77. */
11142 if (ffe_is_do_internal_checks ())
11144 static const char names
[][12]
11146 {"bar", "bletch", "foo", "foobar"};
11151 name
= bsearch ("foo", &names
[0], ARRAY_SIZE (names
), sizeof (names
[0]),
11152 (int (*)(const void *, const void *)) strcmp
);
11153 if (name
!= &names
[2][0])
11155 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11160 ul
= strtoul ("123456789", NULL
, 10);
11161 if (ul
!= 123456789L)
11163 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11164 in proj.h" == NULL
);
11168 fl
= atof ("56.789");
11169 if ((fl
< 56.788) || (fl
> 56.79))
11171 assert ("atof not type double, fix your #include <stdio.h>"
11177 ffecom_outer_function_decl_
= NULL_TREE
;
11178 current_function_decl
= NULL_TREE
;
11179 named_labels
= NULL_TREE
;
11180 current_binding_level
= NULL_BINDING_LEVEL
;
11181 free_binding_level
= NULL_BINDING_LEVEL
;
11182 /* Make the binding_level structure for global names. */
11184 global_binding_level
= current_binding_level
;
11185 current_binding_level
->prep_state
= 2;
11187 build_common_tree_nodes (1);
11189 /* Define `int' and `char' first so that dbx will output them first. */
11190 pushdecl (build_decl (TYPE_DECL
, get_identifier ("int"),
11191 integer_type_node
));
11192 /* CHARACTER*1 is unsigned in ICHAR contexts. */
11193 char_type_node
= make_unsigned_type (CHAR_TYPE_SIZE
);
11194 pushdecl (build_decl (TYPE_DECL
, get_identifier ("char"),
11196 pushdecl (build_decl (TYPE_DECL
, get_identifier ("long int"),
11197 long_integer_type_node
));
11198 pushdecl (build_decl (TYPE_DECL
, get_identifier ("unsigned int"),
11199 unsigned_type_node
));
11200 pushdecl (build_decl (TYPE_DECL
, get_identifier ("long unsigned int"),
11201 long_unsigned_type_node
));
11202 pushdecl (build_decl (TYPE_DECL
, get_identifier ("long long int"),
11203 long_long_integer_type_node
));
11204 pushdecl (build_decl (TYPE_DECL
, get_identifier ("long long unsigned int"),
11205 long_long_unsigned_type_node
));
11206 pushdecl (build_decl (TYPE_DECL
, get_identifier ("short int"),
11207 short_integer_type_node
));
11208 pushdecl (build_decl (TYPE_DECL
, get_identifier ("short unsigned int"),
11209 short_unsigned_type_node
));
11211 /* Set the sizetype before we make other types. This *should* be the
11212 first type we create. */
11215 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE
))));
11216 ffecom_typesize_pointer_
11217 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype
)) / BITS_PER_UNIT
;
11219 build_common_tree_nodes_2 (0);
11221 /* Define both `signed char' and `unsigned char'. */
11222 pushdecl (build_decl (TYPE_DECL
, get_identifier ("signed char"),
11223 signed_char_type_node
));
11225 pushdecl (build_decl (TYPE_DECL
, get_identifier ("unsigned char"),
11226 unsigned_char_type_node
));
11228 pushdecl (build_decl (TYPE_DECL
, get_identifier ("float"),
11230 pushdecl (build_decl (TYPE_DECL
, get_identifier ("double"),
11231 double_type_node
));
11232 pushdecl (build_decl (TYPE_DECL
, get_identifier ("long double"),
11233 long_double_type_node
));
11235 /* For now, override what build_common_tree_nodes has done. */
11236 complex_integer_type_node
= ffecom_make_complex_type_ (integer_type_node
);
11237 complex_float_type_node
= ffecom_make_complex_type_ (float_type_node
);
11238 complex_double_type_node
= ffecom_make_complex_type_ (double_type_node
);
11239 complex_long_double_type_node
11240 = ffecom_make_complex_type_ (long_double_type_node
);
11242 pushdecl (build_decl (TYPE_DECL
, get_identifier ("complex int"),
11243 complex_integer_type_node
));
11244 pushdecl (build_decl (TYPE_DECL
, get_identifier ("complex float"),
11245 complex_float_type_node
));
11246 pushdecl (build_decl (TYPE_DECL
, get_identifier ("complex double"),
11247 complex_double_type_node
));
11248 pushdecl (build_decl (TYPE_DECL
, get_identifier ("complex long double"),
11249 complex_long_double_type_node
));
11251 pushdecl (build_decl (TYPE_DECL
, get_identifier ("void"),
11253 /* We are not going to have real types in C with less than byte alignment,
11254 so we might as well not have any types that claim to have it. */
11255 TYPE_ALIGN (void_type_node
) = BITS_PER_UNIT
;
11256 TYPE_USER_ALIGN (void_type_node
) = 0;
11258 string_type_node
= build_pointer_type (char_type_node
);
11260 ffecom_tree_fun_type_void
11261 = build_function_type (void_type_node
, NULL_TREE
);
11263 ffecom_tree_ptr_to_fun_type_void
11264 = build_pointer_type (ffecom_tree_fun_type_void
);
11266 endlink
= tree_cons (NULL_TREE
, void_type_node
, NULL_TREE
);
11268 t
= tree_cons (NULL_TREE
, float_type_node
, endlink
);
11269 float_ftype_float
= build_function_type (float_type_node
, t
);
11270 t
= tree_cons (NULL_TREE
, float_type_node
, t
);
11271 float_ftype_float_float
= build_function_type (float_type_node
, t
);
11273 t
= tree_cons (NULL_TREE
, double_type_node
, endlink
);
11274 double_ftype_double
= build_function_type (double_type_node
, t
);
11275 t
= tree_cons (NULL_TREE
, double_type_node
, t
);
11276 double_ftype_double_double
= build_function_type (double_type_node
, t
);
11278 t
= tree_cons (NULL_TREE
, long_double_type_node
, endlink
);
11279 ldouble_ftype_ldouble
= build_function_type (long_double_type_node
, t
);
11280 t
= tree_cons (NULL_TREE
, long_double_type_node
, t
);
11281 ldouble_ftype_ldouble_ldouble
= build_function_type (long_double_type_node
,
11284 for (i
= 0; ((size_t) i
) < ARRAY_SIZE (ffecom_tree_type
); ++i
)
11285 for (j
= 0; ((size_t) j
) < ARRAY_SIZE (ffecom_tree_type
[0]); ++j
)
11287 ffecom_tree_type
[i
][j
] = NULL_TREE
;
11288 ffecom_tree_fun_type
[i
][j
] = NULL_TREE
;
11289 ffecom_tree_ptr_to_fun_type
[i
][j
] = NULL_TREE
;
11290 ffecom_f2c_typecode_
[i
][j
] = -1;
11293 /* Set up standard g77 types. Note that INTEGER and LOGICAL are set
11294 to size FLOAT_TYPE_SIZE because they have to be the same size as
11295 REAL, which also is FLOAT_TYPE_SIZE, according to the standard.
11296 Compiler options and other such stuff that change the ways these
11297 types are set should not affect this particular setup. */
11299 ffecom_tree_type
[FFEINFO_basictypeINTEGER
][FFEINFO_kindtypeINTEGER1
]
11300 = t
= make_signed_type (FLOAT_TYPE_SIZE
);
11301 pushdecl (build_decl (TYPE_DECL
, get_identifier ("integer"),
11303 type
= ffetype_new ();
11305 ffeinfo_set_type (FFEINFO_basictypeINTEGER
, FFEINFO_kindtypeINTEGER1
,
11307 ffetype_set_ams (type
,
11308 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11309 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11310 ffetype_set_star (base_type
,
11311 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11313 ffetype_set_kind (base_type
, 1, type
);
11314 ffecom_typesize_integer1_
= ffetype_size (type
);
11315 assert (ffetype_size (type
) == sizeof (ffetargetInteger1
));
11317 ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][FFEINFO_kindtypeINTEGER1
]
11318 = t
= make_unsigned_type (FLOAT_TYPE_SIZE
); /* HOLLERITH means unsigned. */
11319 pushdecl (build_decl (TYPE_DECL
, get_identifier ("unsigned"),
11322 ffecom_tree_type
[FFEINFO_basictypeINTEGER
][FFEINFO_kindtypeINTEGER2
]
11323 = t
= make_signed_type (CHAR_TYPE_SIZE
);
11324 pushdecl (build_decl (TYPE_DECL
, get_identifier ("byte"),
11326 type
= ffetype_new ();
11327 ffeinfo_set_type (FFEINFO_basictypeINTEGER
, FFEINFO_kindtypeINTEGER2
,
11329 ffetype_set_ams (type
,
11330 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11331 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11332 ffetype_set_star (base_type
,
11333 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11335 ffetype_set_kind (base_type
, 3, type
);
11336 assert (ffetype_size (type
) == sizeof (ffetargetInteger2
));
11338 ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][FFEINFO_kindtypeINTEGER2
]
11339 = t
= make_unsigned_type (CHAR_TYPE_SIZE
);
11340 pushdecl (build_decl (TYPE_DECL
, get_identifier ("unsigned byte"),
11343 ffecom_tree_type
[FFEINFO_basictypeINTEGER
][FFEINFO_kindtypeINTEGER3
]
11344 = t
= make_signed_type (CHAR_TYPE_SIZE
* 2);
11345 pushdecl (build_decl (TYPE_DECL
, get_identifier ("word"),
11347 type
= ffetype_new ();
11348 ffeinfo_set_type (FFEINFO_basictypeINTEGER
, FFEINFO_kindtypeINTEGER3
,
11350 ffetype_set_ams (type
,
11351 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11352 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11353 ffetype_set_star (base_type
,
11354 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11356 ffetype_set_kind (base_type
, 6, type
);
11357 assert (ffetype_size (type
) == sizeof (ffetargetInteger3
));
11359 ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][FFEINFO_kindtypeINTEGER3
]
11360 = t
= make_unsigned_type (CHAR_TYPE_SIZE
* 2);
11361 pushdecl (build_decl (TYPE_DECL
, get_identifier ("unsigned word"),
11364 ffecom_tree_type
[FFEINFO_basictypeINTEGER
][FFEINFO_kindtypeINTEGER4
]
11365 = t
= make_signed_type (FLOAT_TYPE_SIZE
* 2);
11366 pushdecl (build_decl (TYPE_DECL
, get_identifier ("integer4"),
11368 type
= ffetype_new ();
11369 ffeinfo_set_type (FFEINFO_basictypeINTEGER
, FFEINFO_kindtypeINTEGER4
,
11371 ffetype_set_ams (type
,
11372 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11373 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11374 ffetype_set_star (base_type
,
11375 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11377 ffetype_set_kind (base_type
, 2, type
);
11378 assert (ffetype_size (type
) == sizeof (ffetargetInteger4
));
11380 ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][FFEINFO_kindtypeINTEGER4
]
11381 = t
= make_unsigned_type (FLOAT_TYPE_SIZE
* 2);
11382 pushdecl (build_decl (TYPE_DECL
, get_identifier ("unsigned4"),
11386 if (ffe_is_do_internal_checks ()
11387 && LONG_TYPE_SIZE
!= FLOAT_TYPE_SIZE
11388 && LONG_TYPE_SIZE
!= CHAR_TYPE_SIZE
11389 && LONG_TYPE_SIZE
!= SHORT_TYPE_SIZE
11390 && LONG_TYPE_SIZE
!= LONG_LONG_TYPE_SIZE
)
11392 fprintf (stderr
, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11397 ffecom_tree_type
[FFEINFO_basictypeLOGICAL
][FFEINFO_kindtypeLOGICAL1
]
11398 = t
= make_signed_type (FLOAT_TYPE_SIZE
);
11399 pushdecl (build_decl (TYPE_DECL
, get_identifier ("logical"),
11401 type
= ffetype_new ();
11403 ffeinfo_set_type (FFEINFO_basictypeLOGICAL
, FFEINFO_kindtypeLOGICAL1
,
11405 ffetype_set_ams (type
,
11406 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11407 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11408 ffetype_set_star (base_type
,
11409 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11411 ffetype_set_kind (base_type
, 1, type
);
11412 assert (ffetype_size (type
) == sizeof (ffetargetLogical1
));
11414 ffecom_tree_type
[FFEINFO_basictypeLOGICAL
][FFEINFO_kindtypeLOGICAL2
]
11415 = t
= make_signed_type (CHAR_TYPE_SIZE
);
11416 pushdecl (build_decl (TYPE_DECL
, get_identifier ("logical2"),
11418 type
= ffetype_new ();
11419 ffeinfo_set_type (FFEINFO_basictypeLOGICAL
, FFEINFO_kindtypeLOGICAL2
,
11421 ffetype_set_ams (type
,
11422 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11423 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11424 ffetype_set_star (base_type
,
11425 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11427 ffetype_set_kind (base_type
, 3, type
);
11428 assert (ffetype_size (type
) == sizeof (ffetargetLogical2
));
11430 ffecom_tree_type
[FFEINFO_basictypeLOGICAL
][FFEINFO_kindtypeLOGICAL3
]
11431 = t
= make_signed_type (CHAR_TYPE_SIZE
* 2);
11432 pushdecl (build_decl (TYPE_DECL
, get_identifier ("logical3"),
11434 type
= ffetype_new ();
11435 ffeinfo_set_type (FFEINFO_basictypeLOGICAL
, FFEINFO_kindtypeLOGICAL3
,
11437 ffetype_set_ams (type
,
11438 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11439 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11440 ffetype_set_star (base_type
,
11441 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11443 ffetype_set_kind (base_type
, 6, type
);
11444 assert (ffetype_size (type
) == sizeof (ffetargetLogical3
));
11446 ffecom_tree_type
[FFEINFO_basictypeLOGICAL
][FFEINFO_kindtypeLOGICAL4
]
11447 = t
= make_signed_type (FLOAT_TYPE_SIZE
* 2);
11448 pushdecl (build_decl (TYPE_DECL
, get_identifier ("logical4"),
11450 type
= ffetype_new ();
11451 ffeinfo_set_type (FFEINFO_basictypeLOGICAL
, FFEINFO_kindtypeLOGICAL4
,
11453 ffetype_set_ams (type
,
11454 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11455 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11456 ffetype_set_star (base_type
,
11457 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11459 ffetype_set_kind (base_type
, 2, type
);
11460 assert (ffetype_size (type
) == sizeof (ffetargetLogical4
));
11462 ffecom_tree_type
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL1
]
11463 = t
= make_node (REAL_TYPE
);
11464 TYPE_PRECISION (t
) = FLOAT_TYPE_SIZE
;
11465 pushdecl (build_decl (TYPE_DECL
, get_identifier ("real"),
11468 type
= ffetype_new ();
11470 ffeinfo_set_type (FFEINFO_basictypeREAL
, FFEINFO_kindtypeREAL1
,
11472 ffetype_set_ams (type
,
11473 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11474 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11475 ffetype_set_star (base_type
,
11476 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11478 ffetype_set_kind (base_type
, 1, type
);
11479 ffecom_f2c_typecode_
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL1
]
11480 = FFETARGET_f2cTYREAL
;
11481 assert (ffetype_size (type
) == sizeof (ffetargetReal1
));
11483 ffecom_tree_type
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREALDOUBLE
]
11484 = t
= make_node (REAL_TYPE
);
11485 TYPE_PRECISION (t
) = FLOAT_TYPE_SIZE
* 2; /* Always twice REAL. */
11486 pushdecl (build_decl (TYPE_DECL
, get_identifier ("double precision"),
11489 type
= ffetype_new ();
11490 ffeinfo_set_type (FFEINFO_basictypeREAL
, FFEINFO_kindtypeREALDOUBLE
,
11492 ffetype_set_ams (type
,
11493 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11494 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11495 ffetype_set_star (base_type
,
11496 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11498 ffetype_set_kind (base_type
, 2, type
);
11499 ffecom_f2c_typecode_
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL2
]
11500 = FFETARGET_f2cTYDREAL
;
11501 assert (ffetype_size (type
) == sizeof (ffetargetReal2
));
11503 ffecom_tree_type
[FFEINFO_basictypeCOMPLEX
][FFEINFO_kindtypeREAL1
]
11504 = t
= ffecom_make_complex_type_ (ffecom_tree_type
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL1
]);
11505 pushdecl (build_decl (TYPE_DECL
, get_identifier ("complex"),
11507 type
= ffetype_new ();
11509 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX
, FFEINFO_kindtypeREAL1
,
11511 ffetype_set_ams (type
,
11512 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11513 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11514 ffetype_set_star (base_type
,
11515 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11517 ffetype_set_kind (base_type
, 1, type
);
11518 ffecom_f2c_typecode_
[FFEINFO_basictypeCOMPLEX
][FFEINFO_kindtypeREAL1
]
11519 = FFETARGET_f2cTYCOMPLEX
;
11520 assert (ffetype_size (type
) == sizeof (ffetargetComplex1
));
11522 ffecom_tree_type
[FFEINFO_basictypeCOMPLEX
][FFEINFO_kindtypeREALDOUBLE
]
11523 = t
= ffecom_make_complex_type_ (ffecom_tree_type
[FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL2
]);
11524 pushdecl (build_decl (TYPE_DECL
, get_identifier ("double complex"),
11526 type
= ffetype_new ();
11527 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX
, FFEINFO_kindtypeREALDOUBLE
,
11529 ffetype_set_ams (type
,
11530 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11531 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11532 ffetype_set_star (base_type
,
11533 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / CHAR_TYPE_SIZE
,
11535 ffetype_set_kind (base_type
, 2,
11537 ffecom_f2c_typecode_
[FFEINFO_basictypeCOMPLEX
][FFEINFO_kindtypeREAL2
]
11538 = FFETARGET_f2cTYDCOMPLEX
;
11539 assert (ffetype_size (type
) == sizeof (ffetargetComplex2
));
11541 /* Make function and ptr-to-function types for non-CHARACTER types. */
11543 for (i
= 0; ((size_t) i
) < ARRAY_SIZE (ffecom_tree_type
); ++i
)
11544 for (j
= 0; ((size_t) j
) < ARRAY_SIZE (ffecom_tree_type
[0]); ++j
)
11546 if ((t
= ffecom_tree_type
[i
][j
]) != NULL_TREE
)
11548 if (i
== FFEINFO_basictypeINTEGER
)
11550 /* Figure out the smallest INTEGER type that can hold
11551 a pointer on this machine. */
11552 if (GET_MODE_SIZE (TYPE_MODE (t
))
11553 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node
))))
11555 if ((ffecom_pointer_kind_
== FFEINFO_kindtypeNONE
)
11556 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type
[i
][ffecom_pointer_kind_
]))
11557 > GET_MODE_SIZE (TYPE_MODE (t
))))
11558 ffecom_pointer_kind_
= j
;
11561 else if (i
== FFEINFO_basictypeCOMPLEX
)
11562 t
= void_type_node
;
11563 /* For f2c compatibility, REAL functions are really
11564 implemented as DOUBLE PRECISION. */
11565 else if ((i
== FFEINFO_basictypeREAL
)
11566 && (j
== FFEINFO_kindtypeREAL1
))
11567 t
= ffecom_tree_type
11568 [FFEINFO_basictypeREAL
][FFEINFO_kindtypeREAL2
];
11570 t
= ffecom_tree_fun_type
[i
][j
] = build_function_type (t
,
11572 ffecom_tree_ptr_to_fun_type
[i
][j
] = build_pointer_type (t
);
11576 /* Set up pointer types. */
11578 if (ffecom_pointer_kind_
== FFEINFO_basictypeNONE
)
11579 fatal_error ("no INTEGER type can hold a pointer on this configuration");
11580 else if (0 && ffe_is_do_internal_checks ())
11581 fprintf (stderr
, "Pointer type kt=%d\n", ffecom_pointer_kind_
);
11582 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER
,
11583 FFEINFO_kindtypeINTEGERDEFAULT
),
11585 ffeinfo_type (FFEINFO_basictypeINTEGER
,
11586 ffecom_pointer_kind_
));
11588 if (ffe_is_ugly_assign ())
11589 ffecom_label_kind_
= ffecom_pointer_kind_
; /* Require ASSIGN etc to this. */
11591 ffecom_label_kind_
= FFEINFO_kindtypeINTEGERDEFAULT
;
11592 if (0 && ffe_is_do_internal_checks ())
11593 fprintf (stderr
, "Label type kt=%d\n", ffecom_label_kind_
);
11595 ffecom_integer_type_node
11596 = ffecom_tree_type
[FFEINFO_basictypeINTEGER
][FFEINFO_kindtypeINTEGER1
];
11597 ffecom_integer_zero_node
= convert (ffecom_integer_type_node
,
11598 integer_zero_node
);
11599 ffecom_integer_one_node
= convert (ffecom_integer_type_node
,
11602 /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional.
11603 Turns out that by TYLONG, runtime/libI77/lio.h really means
11604 "whatever size an ftnint is". For consistency and sanity,
11605 com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen
11606 all are INTEGER, which we also make out of whatever back-end
11607 integer type is FLOAT_TYPE_SIZE bits wide. This change, from
11608 LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to
11609 accommodate machines like the Alpha. Note that this suggests
11610 f2c and libf2c are missing a distinction perhaps needed on
11611 some machines between "int" and "long int". -- burley 0.5.5 950215 */
11613 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER
, FLOAT_TYPE_SIZE
,
11614 FFETARGET_f2cTYLONG
);
11615 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER
, SHORT_TYPE_SIZE
,
11616 FFETARGET_f2cTYSHORT
);
11617 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER
, CHAR_TYPE_SIZE
,
11618 FFETARGET_f2cTYINT1
);
11619 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER
, LONG_LONG_TYPE_SIZE
,
11620 FFETARGET_f2cTYQUAD
);
11621 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL
, FLOAT_TYPE_SIZE
,
11622 FFETARGET_f2cTYLOGICAL
);
11623 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL
, SHORT_TYPE_SIZE
,
11624 FFETARGET_f2cTYLOGICAL2
);
11625 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL
, CHAR_TYPE_SIZE
,
11626 FFETARGET_f2cTYLOGICAL1
);
11627 /* ~~~Not really such a type in libf2c, e.g. I/O support? */
11628 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL
, LONG_LONG_TYPE_SIZE
,
11629 FFETARGET_f2cTYQUAD
);
11631 /* CHARACTER stuff is all special-cased, so it is not handled in the above
11632 loop. CHARACTER items are built as arrays of unsigned char. */
11634 ffecom_tree_type
[FFEINFO_basictypeCHARACTER
]
11635 [FFEINFO_kindtypeCHARACTER1
] = t
= char_type_node
;
11636 type
= ffetype_new ();
11638 ffeinfo_set_type (FFEINFO_basictypeCHARACTER
,
11639 FFEINFO_kindtypeCHARACTER1
,
11641 ffetype_set_ams (type
,
11642 TYPE_ALIGN (t
) / BITS_PER_UNIT
, 0,
11643 TREE_INT_CST_LOW (TYPE_SIZE (t
)) / BITS_PER_UNIT
);
11644 ffetype_set_kind (base_type
, 1, type
);
11645 assert (ffetype_size (type
)
11646 == sizeof (((ffetargetCharacter1
) { 0, NULL
}).text
[0]));
11648 ffecom_tree_fun_type
[FFEINFO_basictypeCHARACTER
]
11649 [FFEINFO_kindtypeCHARACTER1
] = ffecom_tree_fun_type_void
;
11650 ffecom_tree_ptr_to_fun_type
[FFEINFO_basictypeCHARACTER
]
11651 [FFEINFO_kindtypeCHARACTER1
]
11652 = ffecom_tree_ptr_to_fun_type_void
;
11653 ffecom_f2c_typecode_
[FFEINFO_basictypeCHARACTER
][FFEINFO_kindtypeCHARACTER1
]
11654 = FFETARGET_f2cTYCHAR
;
11656 ffecom_f2c_typecode_
[FFEINFO_basictypeANY
][FFEINFO_kindtypeANY
]
11659 /* Make multi-return-value type and fields. */
11661 ffecom_multi_type_node_
= make_node (UNION_TYPE
);
11665 for (i
= 0; ((size_t) i
) < ARRAY_SIZE (ffecom_tree_type
); ++i
)
11666 for (j
= 0; ((size_t) j
) < ARRAY_SIZE (ffecom_tree_type
[0]); ++j
)
11670 if (ffecom_tree_type
[i
][j
] == NULL_TREE
)
11671 continue; /* Not supported. */
11672 sprintf (&name
[0], "bt_%s_kt_%s",
11673 ffeinfo_basictype_string ((ffeinfoBasictype
) i
),
11674 ffeinfo_kindtype_string ((ffeinfoKindtype
) j
));
11675 ffecom_multi_fields_
[i
][j
] = build_decl (FIELD_DECL
,
11676 get_identifier (name
),
11677 ffecom_tree_type
[i
][j
]);
11678 DECL_CONTEXT (ffecom_multi_fields_
[i
][j
])
11679 = ffecom_multi_type_node_
;
11680 DECL_ALIGN (ffecom_multi_fields_
[i
][j
]) = 0;
11681 DECL_USER_ALIGN (ffecom_multi_fields_
[i
][j
]) = 0;
11682 TREE_CHAIN (ffecom_multi_fields_
[i
][j
]) = field
;
11683 field
= ffecom_multi_fields_
[i
][j
];
11686 TYPE_FIELDS (ffecom_multi_type_node_
) = field
;
11687 layout_type (ffecom_multi_type_node_
);
11689 /* Subroutines usually return integer because they might have alternate
11692 ffecom_tree_subr_type
11693 = build_function_type (integer_type_node
, NULL_TREE
);
11694 ffecom_tree_ptr_to_subr_type
11695 = build_pointer_type (ffecom_tree_subr_type
);
11696 ffecom_tree_blockdata_type
11697 = build_function_type (void_type_node
, NULL_TREE
);
11699 builtin_function ("__builtin_atanf", float_ftype_float
,
11700 BUILT_IN_ATANF
, BUILT_IN_NORMAL
, "atanf", NULL_TREE
);
11701 builtin_function ("__builtin_atan", double_ftype_double
,
11702 BUILT_IN_ATAN
, BUILT_IN_NORMAL
, "atan", NULL_TREE
);
11703 builtin_function ("__builtin_atanl", ldouble_ftype_ldouble
,
11704 BUILT_IN_ATANL
, BUILT_IN_NORMAL
, "atanl", NULL_TREE
);
11706 builtin_function ("__builtin_atan2f", float_ftype_float_float
,
11707 BUILT_IN_ATAN2F
, BUILT_IN_NORMAL
, "atan2f", NULL_TREE
);
11708 builtin_function ("__builtin_atan2", double_ftype_double_double
,
11709 BUILT_IN_ATAN2
, BUILT_IN_NORMAL
, "atan2", NULL_TREE
);
11710 builtin_function ("__builtin_atan2l", ldouble_ftype_ldouble_ldouble
,
11711 BUILT_IN_ATAN2L
, BUILT_IN_NORMAL
, "atan2l", NULL_TREE
);
11713 builtin_function ("__builtin_cosf", float_ftype_float
,
11714 BUILT_IN_COSF
, BUILT_IN_NORMAL
, "cosf", NULL_TREE
);
11715 builtin_function ("__builtin_cos", double_ftype_double
,
11716 BUILT_IN_COS
, BUILT_IN_NORMAL
, "cos", NULL_TREE
);
11717 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble
,
11718 BUILT_IN_COSL
, BUILT_IN_NORMAL
, "cosl", NULL_TREE
);
11720 builtin_function ("__builtin_expf", float_ftype_float
,
11721 BUILT_IN_EXPF
, BUILT_IN_NORMAL
, "expf", NULL_TREE
);
11722 builtin_function ("__builtin_exp", double_ftype_double
,
11723 BUILT_IN_EXP
, BUILT_IN_NORMAL
, "exp", NULL_TREE
);
11724 builtin_function ("__builtin_expl", ldouble_ftype_ldouble
,
11725 BUILT_IN_EXPL
, BUILT_IN_NORMAL
, "expl", NULL_TREE
);
11727 builtin_function ("__builtin_floorf", float_ftype_float
,
11728 BUILT_IN_FLOORF
, BUILT_IN_NORMAL
, "floorf", NULL_TREE
);
11729 builtin_function ("__builtin_floor", double_ftype_double
,
11730 BUILT_IN_FLOOR
, BUILT_IN_NORMAL
, "floor", NULL_TREE
);
11731 builtin_function ("__builtin_floorl", ldouble_ftype_ldouble
,
11732 BUILT_IN_FLOORL
, BUILT_IN_NORMAL
, "floorl", NULL_TREE
);
11734 builtin_function ("__builtin_fmodf", float_ftype_float_float
,
11735 BUILT_IN_FMODF
, BUILT_IN_NORMAL
, "fmodf", NULL_TREE
);
11736 builtin_function ("__builtin_fmod", double_ftype_double_double
,
11737 BUILT_IN_FMOD
, BUILT_IN_NORMAL
, "fmod", NULL_TREE
);
11738 builtin_function ("__builtin_fmodl", ldouble_ftype_ldouble_ldouble
,
11739 BUILT_IN_FMODL
, BUILT_IN_NORMAL
, "fmodl", NULL_TREE
);
11741 builtin_function ("__builtin_logf", float_ftype_float
,
11742 BUILT_IN_LOGF
, BUILT_IN_NORMAL
, "logf", NULL_TREE
);
11743 builtin_function ("__builtin_log", double_ftype_double
,
11744 BUILT_IN_LOG
, BUILT_IN_NORMAL
, "log", NULL_TREE
);
11745 builtin_function ("__builtin_logl", ldouble_ftype_ldouble
,
11746 BUILT_IN_LOGL
, BUILT_IN_NORMAL
, "logl", NULL_TREE
);
11748 builtin_function ("__builtin_powf", float_ftype_float_float
,
11749 BUILT_IN_POWF
, BUILT_IN_NORMAL
, "powf", NULL_TREE
);
11750 builtin_function ("__builtin_pow", double_ftype_double_double
,
11751 BUILT_IN_POW
, BUILT_IN_NORMAL
, "pow", NULL_TREE
);
11752 builtin_function ("__builtin_powl", ldouble_ftype_ldouble_ldouble
,
11753 BUILT_IN_POWL
, BUILT_IN_NORMAL
, "powl", NULL_TREE
);
11755 builtin_function ("__builtin_sinf", float_ftype_float
,
11756 BUILT_IN_SINF
, BUILT_IN_NORMAL
, "sinf", NULL_TREE
);
11757 builtin_function ("__builtin_sin", double_ftype_double
,
11758 BUILT_IN_SIN
, BUILT_IN_NORMAL
, "sin", NULL_TREE
);
11759 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble
,
11760 BUILT_IN_SINL
, BUILT_IN_NORMAL
, "sinl", NULL_TREE
);
11762 builtin_function ("__builtin_sqrtf", float_ftype_float
,
11763 BUILT_IN_SQRTF
, BUILT_IN_NORMAL
, "sqrtf", NULL_TREE
);
11764 builtin_function ("__builtin_sqrt", double_ftype_double
,
11765 BUILT_IN_SQRT
, BUILT_IN_NORMAL
, "sqrt", NULL_TREE
);
11766 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble
,
11767 BUILT_IN_SQRTL
, BUILT_IN_NORMAL
, "sqrtl", NULL_TREE
);
11769 builtin_function ("__builtin_tanf", float_ftype_float
,
11770 BUILT_IN_TANF
, BUILT_IN_NORMAL
, "tanf", NULL_TREE
);
11771 builtin_function ("__builtin_tan", double_ftype_double
,
11772 BUILT_IN_TAN
, BUILT_IN_NORMAL
, "tan", NULL_TREE
);
11773 builtin_function ("__builtin_tanl", ldouble_ftype_ldouble
,
11774 BUILT_IN_TANL
, BUILT_IN_NORMAL
, "tanl", NULL_TREE
);
11776 pedantic_lvalues
= FALSE
;
11778 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node
,
11781 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node
,
11784 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node
,
11787 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node
,
11788 FFECOM_f2cDOUBLEREAL
,
11790 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node
,
11793 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node
,
11794 FFECOM_f2cDOUBLECOMPLEX
,
11796 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node
,
11799 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node
,
11802 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node
,
11805 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node
,
11808 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node
,
11812 ffecom_f2c_ftnlen_zero_node
11813 = convert (ffecom_f2c_ftnlen_type_node
, integer_zero_node
);
11815 ffecom_f2c_ftnlen_one_node
11816 = convert (ffecom_f2c_ftnlen_type_node
, integer_one_node
);
11818 ffecom_f2c_ftnlen_two_node
= build_int_2 (2, 0);
11819 TREE_TYPE (ffecom_f2c_ftnlen_two_node
) = ffecom_integer_type_node
;
11821 ffecom_f2c_ptr_to_ftnlen_type_node
11822 = build_pointer_type (ffecom_f2c_ftnlen_type_node
);
11824 ffecom_f2c_ptr_to_ftnint_type_node
11825 = build_pointer_type (ffecom_f2c_ftnint_type_node
);
11827 ffecom_f2c_ptr_to_integer_type_node
11828 = build_pointer_type (ffecom_f2c_integer_type_node
);
11830 ffecom_f2c_ptr_to_real_type_node
11831 = build_pointer_type (ffecom_f2c_real_type_node
);
11833 ffecom_float_zero_
= build_real (float_type_node
, dconst0
);
11834 ffecom_double_zero_
= build_real (double_type_node
, dconst0
);
11836 REAL_VALUE_TYPE point_5
;
11838 REAL_ARITHMETIC (point_5
, RDIV_EXPR
, dconst1
, dconst2
);
11839 ffecom_float_half_
= build_real (float_type_node
, point_5
);
11840 ffecom_double_half_
= build_real (double_type_node
, point_5
);
11843 /* Do "extern int xargc;". */
11845 ffecom_tree_xargc_
= build_decl (VAR_DECL
,
11846 get_identifier ("f__xargc"),
11847 integer_type_node
);
11848 DECL_EXTERNAL (ffecom_tree_xargc_
) = 1;
11849 TREE_STATIC (ffecom_tree_xargc_
) = 1;
11850 TREE_PUBLIC (ffecom_tree_xargc_
) = 1;
11851 ffecom_tree_xargc_
= start_decl (ffecom_tree_xargc_
, FALSE
);
11852 finish_decl (ffecom_tree_xargc_
, NULL_TREE
, FALSE
);
11854 #if 0 /* This is being fixed, and seems to be working now. */
11855 if ((FLOAT_TYPE_SIZE
!= 32)
11856 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node
))) != 32))
11858 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
11859 (int) FLOAT_TYPE_SIZE
);
11860 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
11861 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node
))));
11862 warning ("properly unless they all are 32 bits wide");
11863 warning ("Please keep this in mind before you report bugs.");
11867 #if 0 /* Code in ste.c that would crash has been commented out. */
11868 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node
)
11869 < TYPE_PRECISION (string_type_node
))
11870 /* I/O will probably crash. */
11871 warning ("configuration: char * holds %d bits, but ftnlen only %d",
11872 TYPE_PRECISION (string_type_node
),
11873 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node
));
11876 #if 0 /* ASSIGN-related stuff has been changed to accommodate this. */
11877 if (TYPE_PRECISION (ffecom_integer_type_node
)
11878 < TYPE_PRECISION (string_type_node
))
11879 /* ASSIGN 10 TO I will crash. */
11880 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
11881 ASSIGN statement might fail",
11882 TYPE_PRECISION (string_type_node
),
11883 TYPE_PRECISION (ffecom_integer_type_node
));
11887 /* ffecom_init_2 -- Initialize
11889 ffecom_init_2(); */
11894 assert (ffecom_outer_function_decl_
== NULL_TREE
);
11895 assert (current_function_decl
== NULL_TREE
);
11896 assert (ffecom_which_entrypoint_decl_
== NULL_TREE
);
11898 ffecom_master_arglist_
= NULL
;
11900 ffecom_primary_entry_
= NULL
;
11901 ffecom_is_altreturning_
= FALSE
;
11902 ffecom_func_result_
= NULL_TREE
;
11903 ffecom_multi_retval_
= NULL_TREE
;
11906 /* ffecom_list_expr -- Transform list of exprs into gcc tree
11909 ffebld expr; // FFE opITEM list.
11910 tree = ffecom_list_expr(expr);
11912 List of actual args is transformed into corresponding gcc backend list. */
11915 ffecom_list_expr (ffebld expr
)
11918 tree
*plist
= &list
;
11919 tree trail
= NULL_TREE
; /* Append char length args here. */
11920 tree
*ptrail
= &trail
;
11923 while (expr
!= NULL
)
11925 tree texpr
= ffecom_arg_expr (ffebld_head (expr
), &length
);
11927 if (texpr
== error_mark_node
)
11928 return error_mark_node
;
11930 *plist
= build_tree_list (NULL_TREE
, texpr
);
11931 plist
= &TREE_CHAIN (*plist
);
11932 expr
= ffebld_trail (expr
);
11933 if (length
!= NULL_TREE
)
11935 *ptrail
= build_tree_list (NULL_TREE
, length
);
11936 ptrail
= &TREE_CHAIN (*ptrail
);
11945 /* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree
11948 ffebld expr; // FFE opITEM list.
11949 tree = ffecom_list_ptr_to_expr(expr);
11951 List of actual args is transformed into corresponding gcc backend list for
11952 use in calling an external procedure (vs. a statement function). */
11955 ffecom_list_ptr_to_expr (ffebld expr
)
11958 tree
*plist
= &list
;
11959 tree trail
= NULL_TREE
; /* Append char length args here. */
11960 tree
*ptrail
= &trail
;
11963 while (expr
!= NULL
)
11965 tree texpr
= ffecom_arg_ptr_to_expr (ffebld_head (expr
), &length
);
11967 if (texpr
== error_mark_node
)
11968 return error_mark_node
;
11970 *plist
= build_tree_list (NULL_TREE
, texpr
);
11971 plist
= &TREE_CHAIN (*plist
);
11972 expr
= ffebld_trail (expr
);
11973 if (length
!= NULL_TREE
)
11975 *ptrail
= build_tree_list (NULL_TREE
, length
);
11976 ptrail
= &TREE_CHAIN (*ptrail
);
11985 /* Obtain gcc's LABEL_DECL tree for label. */
11988 ffecom_lookup_label (ffelab label
)
11992 if (ffelab_hook (label
) == NULL_TREE
)
11994 char labelname
[16];
11996 switch (ffelab_type (label
))
11998 case FFELAB_typeLOOPEND
:
11999 case FFELAB_typeNOTLOOP
:
12000 case FFELAB_typeENDIF
:
12001 sprintf (labelname
, "%" ffelabValue_f
"u", ffelab_value (label
));
12002 glabel
= build_decl (LABEL_DECL
, get_identifier (labelname
),
12004 DECL_CONTEXT (glabel
) = current_function_decl
;
12005 DECL_MODE (glabel
) = VOIDmode
;
12008 case FFELAB_typeFORMAT
:
12009 glabel
= build_decl (VAR_DECL
,
12010 ffecom_get_invented_identifier
12011 ("__g77_format_%d", (int) ffelab_value (label
)),
12012 build_type_variant (build_array_type
12016 TREE_CONSTANT (glabel
) = 1;
12017 TREE_STATIC (glabel
) = 1;
12018 DECL_CONTEXT (glabel
) = current_function_decl
;
12019 DECL_INITIAL (glabel
) = NULL
;
12020 make_decl_rtl (glabel
, NULL
);
12021 expand_decl (glabel
);
12023 ffecom_save_tree_forever (glabel
);
12027 case FFELAB_typeANY
:
12028 glabel
= error_mark_node
;
12032 assert ("bad label type" == NULL
);
12036 ffelab_set_hook (label
, glabel
);
12040 glabel
= ffelab_hook (label
);
12046 /* Stabilizes the arguments. Don't use this if the lhs and rhs come from
12047 a single source specification (as in the fourth argument of MVBITS).
12048 If the type is NULL_TREE, the type of lhs is used to make the type of
12049 the MODIFY_EXPR. */
12052 ffecom_modify (tree newtype
, tree lhs
,
12055 if (lhs
== error_mark_node
|| rhs
== error_mark_node
)
12056 return error_mark_node
;
12058 if (newtype
== NULL_TREE
)
12059 newtype
= TREE_TYPE (lhs
);
12061 if (TREE_SIDE_EFFECTS (lhs
))
12062 lhs
= stabilize_reference (lhs
);
12064 return ffecom_2s (MODIFY_EXPR
, newtype
, lhs
, rhs
);
12067 /* Register source file name. */
12070 ffecom_file (const char *name
)
12072 ffecom_file_ (name
);
12075 /* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed
12078 ffecom_notify_init_storage(st);
12080 Gets called when all possible units in an aggregate storage area (a LOCAL
12081 with equivalences or a COMMON) have been initialized. The initialization
12082 info either is in ffestorag_init or, if that is NULL,
12083 ffestorag_accretion:
12085 ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur
12086 even for an array if the array is one element in length!
12088 ffestorag_accretion will contain an opACCTER. It is much like an
12089 opARRTER except it has an ffebit object in it instead of just a size.
12090 The back end can use the info in the ffebit object, if it wants, to
12091 reduce the amount of actual initialization, but in any case it should
12092 kill the ffebit object when done. Also, set accretion to NULL but
12093 init to a non-NULL value.
12095 After performing initialization, DO NOT set init to NULL, because that'll
12096 tell the front end it is ok for more initialization to happen. Instead,
12097 set init to an opANY expression or some such thing that you can use to
12098 tell that you've already initialized the object.
12101 Support two-pass FFE. */
12104 ffecom_notify_init_storage (ffestorag st
)
12106 ffebld init
; /* The initialization expression. */
12108 if (ffestorag_init (st
) == NULL
)
12110 init
= ffestorag_accretion (st
);
12111 assert (init
!= NULL
);
12112 ffestorag_set_accretion (st
, NULL
);
12113 ffestorag_set_accretes (st
, 0);
12114 ffestorag_set_init (st
, init
);
12118 /* ffecom_notify_init_symbol -- A symbol is now fully init'ed
12121 ffecom_notify_init_symbol(s);
12123 Gets called when all possible units in a symbol (not placed in COMMON
12124 or involved in EQUIVALENCE, unless it as yet has no ffestorag object)
12125 have been initialized. The initialization info either is in
12126 ffesymbol_init or, if that is NULL, ffesymbol_accretion:
12128 ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur
12129 even for an array if the array is one element in length!
12131 ffesymbol_accretion will contain an opACCTER. It is much like an
12132 opARRTER except it has an ffebit object in it instead of just a size.
12133 The back end can use the info in the ffebit object, if it wants, to
12134 reduce the amount of actual initialization, but in any case it should
12135 kill the ffebit object when done. Also, set accretion to NULL but
12136 init to a non-NULL value.
12138 After performing initialization, DO NOT set init to NULL, because that'll
12139 tell the front end it is ok for more initialization to happen. Instead,
12140 set init to an opANY expression or some such thing that you can use to
12141 tell that you've already initialized the object.
12144 Support two-pass FFE. */
12147 ffecom_notify_init_symbol (ffesymbol s
)
12149 ffebld init
; /* The initialization expression. */
12151 if (ffesymbol_storage (s
) == NULL
)
12152 return; /* Do nothing until COMMON/EQUIVALENCE
12153 possibilities checked. */
12155 if ((ffesymbol_init (s
) == NULL
)
12156 && ((init
= ffesymbol_accretion (s
)) != NULL
))
12158 ffesymbol_set_accretion (s
, NULL
);
12159 ffesymbol_set_accretes (s
, 0);
12160 ffesymbol_set_init (s
, init
);
12164 /* ffecom_notify_primary_entry -- Learn which is the primary entry point
12167 ffecom_notify_primary_entry(s);
12169 Gets called when implicit or explicit PROGRAM statement seen or when
12170 FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary
12171 global symbol that serves as the entry point. */
12174 ffecom_notify_primary_entry (ffesymbol s
)
12176 ffecom_primary_entry_
= s
;
12177 ffecom_primary_entry_kind_
= ffesymbol_kind (s
);
12179 if ((ffecom_primary_entry_kind_
== FFEINFO_kindFUNCTION
)
12180 || (ffecom_primary_entry_kind_
== FFEINFO_kindSUBROUTINE
))
12181 ffecom_primary_entry_is_proc_
= TRUE
;
12183 ffecom_primary_entry_is_proc_
= FALSE
;
12185 if (!ffe_is_silent ())
12187 if (ffecom_primary_entry_kind_
== FFEINFO_kindPROGRAM
)
12188 fprintf (stderr
, "%s:\n", ffesymbol_text (s
));
12190 fprintf (stderr
, " %s:\n", ffesymbol_text (s
));
12193 if (ffecom_primary_entry_kind_
== FFEINFO_kindSUBROUTINE
)
12198 for (list
= ffesymbol_dummyargs (s
);
12200 list
= ffebld_trail (list
))
12202 arg
= ffebld_head (list
);
12203 if (ffebld_op (arg
) == FFEBLD_opSTAR
)
12205 ffecom_is_altreturning_
= TRUE
;
12213 ffecom_open_include (char *name
, ffewhereLine l
, ffewhereColumn c
)
12215 return ffecom_open_include_ (name
, l
, c
);
12218 /* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front
12221 ffebld expr; // FFE expression.
12222 tree = ffecom_ptr_to_expr(expr);
12224 Like ffecom_expr, but sticks address-of in front of most things. */
12227 ffecom_ptr_to_expr (ffebld expr
)
12230 ffeinfoBasictype bt
;
12231 ffeinfoKindtype kt
;
12234 assert (expr
!= NULL
);
12236 switch (ffebld_op (expr
))
12238 case FFEBLD_opSYMTER
:
12239 s
= ffebld_symter (expr
);
12240 if (ffesymbol_where (s
) == FFEINFO_whereINTRINSIC
)
12244 ix
= ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr
));
12245 assert (ix
!= FFECOM_gfrt
);
12246 if ((item
= ffecom_gfrt_
[ix
]) == NULL_TREE
)
12248 ffecom_make_gfrt_ (ix
);
12249 item
= ffecom_gfrt_
[ix
];
12254 item
= ffesymbol_hook (s
).decl_tree
;
12255 if (item
== NULL_TREE
)
12257 s
= ffecom_sym_transform_ (s
);
12258 item
= ffesymbol_hook (s
).decl_tree
;
12261 assert (item
!= NULL
);
12262 if (item
== error_mark_node
)
12264 if (!ffesymbol_hook (s
).addr
)
12265 item
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (item
)),
12269 case FFEBLD_opARRAYREF
:
12270 return ffecom_arrayref_ (NULL_TREE
, expr
, 1);
12272 case FFEBLD_opCONTER
:
12274 bt
= ffeinfo_basictype (ffebld_info (expr
));
12275 kt
= ffeinfo_kindtype (ffebld_info (expr
));
12277 item
= ffecom_constantunion (&ffebld_constant_union
12278 (ffebld_conter (expr
)), bt
, kt
,
12279 ffecom_tree_type
[bt
][kt
]);
12280 if (item
== error_mark_node
)
12281 return error_mark_node
;
12282 item
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (item
)),
12287 return error_mark_node
;
12290 bt
= ffeinfo_basictype (ffebld_info (expr
));
12291 kt
= ffeinfo_kindtype (ffebld_info (expr
));
12293 item
= ffecom_expr (expr
);
12294 if (item
== error_mark_node
)
12295 return error_mark_node
;
12297 /* The back end currently optimizes a bit too zealously for us, in that
12298 we fail JCB001 if the following block of code is omitted. It checks
12299 to see if the transformed expression is a symbol or array reference,
12300 and encloses it in a SAVE_EXPR if that is the case. */
12303 if ((TREE_CODE (item
) == VAR_DECL
)
12304 || (TREE_CODE (item
) == PARM_DECL
)
12305 || (TREE_CODE (item
) == RESULT_DECL
)
12306 || (TREE_CODE (item
) == INDIRECT_REF
)
12307 || (TREE_CODE (item
) == ARRAY_REF
)
12308 || (TREE_CODE (item
) == COMPONENT_REF
)
12310 || (TREE_CODE (item
) == OFFSET_REF
)
12312 || (TREE_CODE (item
) == BUFFER_REF
)
12313 || (TREE_CODE (item
) == REALPART_EXPR
)
12314 || (TREE_CODE (item
) == IMAGPART_EXPR
))
12316 item
= ffecom_save_tree (item
);
12319 item
= ffecom_1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (item
)),
12324 assert ("fall-through error" == NULL
);
12325 return error_mark_node
;
12328 /* Obtain a temp var with given data type.
12330 size is FFETARGET_charactersizeNONE for a non-CHARACTER type
12331 or >= 0 for a CHARACTER type.
12333 elements is -1 for a scalar or > 0 for an array of type. */
12336 ffecom_make_tempvar (const char *commentary
, tree type
,
12337 ffetargetCharacterSize size
, int elements
)
12340 static int mynumber
;
12342 assert (current_binding_level
->prep_state
< 2);
12344 if (type
== error_mark_node
)
12345 return error_mark_node
;
12347 if (size
!= FFETARGET_charactersizeNONE
)
12348 type
= build_array_type (type
,
12349 build_range_type (ffecom_f2c_ftnlen_type_node
,
12350 ffecom_f2c_ftnlen_one_node
,
12351 build_int_2 (size
, 0)));
12352 if (elements
!= -1)
12353 type
= build_array_type (type
,
12354 build_range_type (integer_type_node
,
12356 build_int_2 (elements
- 1,
12358 t
= build_decl (VAR_DECL
,
12359 ffecom_get_invented_identifier ("__g77_%s_%d",
12364 t
= start_decl (t
, FALSE
);
12365 finish_decl (t
, NULL_TREE
, FALSE
);
12370 /* Prepare argument pointer to expression.
12372 Like ffecom_prepare_expr, except for expressions to be evaluated
12373 via ffecom_arg_ptr_to_expr. */
12376 ffecom_prepare_arg_ptr_to_expr (ffebld expr
)
12378 /* ~~For now, it seems to be the same thing. */
12379 ffecom_prepare_expr (expr
);
12383 /* End of preparations. */
12386 ffecom_prepare_end (void)
12388 int prep_state
= current_binding_level
->prep_state
;
12390 assert (prep_state
< 2);
12391 current_binding_level
->prep_state
= 2;
12393 return (prep_state
== 1) ? TRUE
: FALSE
;
12396 /* Prepare expression.
12398 This is called before any code is generated for the current block.
12399 It scans the expression, declares any temporaries that might be needed
12400 during evaluation of the expression, and stores those temporaries in
12401 the appropriate "hook" fields of the expression. `dest', if not NULL,
12402 specifies the destination that ffecom_expr_ will see, in case that
12403 helps avoid generating unused temporaries.
12405 ~~Improve to avoid allocating unused temporaries by taking `dest'
12406 into account vis-a-vis aliasing requirements of complex/character
12410 ffecom_prepare_expr_ (ffebld expr
, ffebld dest UNUSED
)
12412 ffeinfoBasictype bt
;
12413 ffeinfoKindtype kt
;
12414 ffetargetCharacterSize sz
;
12415 tree tempvar
= NULL_TREE
;
12417 assert (current_binding_level
->prep_state
< 2);
12422 bt
= ffeinfo_basictype (ffebld_info (expr
));
12423 kt
= ffeinfo_kindtype (ffebld_info (expr
));
12424 sz
= ffeinfo_size (ffebld_info (expr
));
12426 /* Generate whatever temporaries are needed to represent the result
12427 of the expression. */
12429 if (bt
== FFEINFO_basictypeCHARACTER
)
12431 while (ffebld_op (expr
) == FFEBLD_opPAREN
)
12432 expr
= ffebld_left (expr
);
12435 switch (ffebld_op (expr
))
12438 /* Don't make temps for SYMTER, CONTER, etc. */
12439 if (ffebld_arity (expr
) == 0)
12444 case FFEINFO_basictypeCOMPLEX
:
12445 if (ffebld_op (expr
) == FFEBLD_opFUNCREF
)
12449 if (ffebld_op (ffebld_left (expr
)) != FFEBLD_opSYMTER
)
12452 s
= ffebld_symter (ffebld_left (expr
));
12453 if (ffesymbol_where (s
) == FFEINFO_whereCONSTANT
12454 || (ffesymbol_where (s
) != FFEINFO_whereINTRINSIC
12455 && ! ffesymbol_is_f2c (s
))
12456 || (ffesymbol_where (s
) == FFEINFO_whereINTRINSIC
12457 && ! ffe_is_f2c_library ()))
12460 else if (ffebld_op (expr
) == FFEBLD_opPOWER
)
12462 /* Requires special treatment. There's no POW_CC function
12463 in libg2c, so POW_ZZ is used, which means we always
12464 need a double-complex temp, not a single-complex. */
12465 kt
= FFEINFO_kindtypeREAL2
;
12467 else if (ffebld_op (expr
) != FFEBLD_opDIVIDE
)
12468 /* The other ops don't need temps for complex operands. */
12471 /* ~~~Avoid making temps for some intrinsics, such as AIMAG(C),
12472 REAL(C). See 19990325-0.f, routine `check', for cases. */
12473 tempvar
= ffecom_make_tempvar ("complex",
12475 [FFEINFO_basictypeCOMPLEX
][kt
],
12476 FFETARGET_charactersizeNONE
,
12480 case FFEINFO_basictypeCHARACTER
:
12481 if (ffebld_op (expr
) != FFEBLD_opFUNCREF
)
12484 if (sz
== FFETARGET_charactersizeNONE
)
12485 /* ~~Kludge alert! This should someday be fixed. */
12488 tempvar
= ffecom_make_tempvar ("char", char_type_node
, sz
, -1);
12496 case FFEBLD_opCONCATENATE
:
12498 /* This gets special handling, because only one set of temps
12499 is needed for a tree of these -- the tree is treated as
12500 a flattened list of concatenations when generating code. */
12502 ffecomConcatList_ catlist
;
12503 tree ltmp
, itmp
, result
;
12507 catlist
= ffecom_concat_list_new_ (expr
, FFETARGET_charactersizeNONE
);
12508 count
= ffecom_concat_list_count_ (catlist
);
12513 = ffecom_make_tempvar ("concat_len",
12514 ffecom_f2c_ftnlen_type_node
,
12515 FFETARGET_charactersizeNONE
, count
);
12517 = ffecom_make_tempvar ("concat_item",
12518 ffecom_f2c_address_type_node
,
12519 FFETARGET_charactersizeNONE
, count
);
12521 = ffecom_make_tempvar ("concat_res",
12523 ffecom_concat_list_maxlen_ (catlist
),
12526 tempvar
= make_tree_vec (3);
12527 TREE_VEC_ELT (tempvar
, 0) = ltmp
;
12528 TREE_VEC_ELT (tempvar
, 1) = itmp
;
12529 TREE_VEC_ELT (tempvar
, 2) = result
;
12532 for (i
= 0; i
< count
; ++i
)
12533 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist
,
12536 ffecom_concat_list_kill_ (catlist
);
12540 ffebld_nonter_set_hook (expr
, tempvar
);
12541 current_binding_level
->prep_state
= 1;
12546 case FFEBLD_opCONVERT
:
12547 if (bt
== FFEINFO_basictypeCHARACTER
12548 && ((ffebld_size_known (ffebld_left (expr
))
12549 == FFETARGET_charactersizeNONE
)
12550 || (ffebld_size_known (ffebld_left (expr
)) >= sz
)))
12551 tempvar
= ffecom_make_tempvar ("convert", char_type_node
, sz
, -1);
12557 ffebld_nonter_set_hook (expr
, tempvar
);
12558 current_binding_level
->prep_state
= 1;
12561 /* Prepare subexpressions for this expr. */
12563 switch (ffebld_op (expr
))
12565 case FFEBLD_opPERCENT_LOC
:
12566 ffecom_prepare_ptr_to_expr (ffebld_left (expr
));
12569 case FFEBLD_opPERCENT_VAL
:
12570 case FFEBLD_opPERCENT_REF
:
12571 ffecom_prepare_expr (ffebld_left (expr
));
12574 case FFEBLD_opPERCENT_DESCR
:
12575 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr
));
12578 case FFEBLD_opITEM
:
12584 item
= ffebld_trail (item
))
12585 if (ffebld_head (item
) != NULL
)
12586 ffecom_prepare_expr (ffebld_head (item
));
12591 /* Need to handle character conversion specially. */
12592 switch (ffebld_arity (expr
))
12595 ffecom_prepare_expr (ffebld_left (expr
));
12596 ffecom_prepare_expr (ffebld_right (expr
));
12600 ffecom_prepare_expr (ffebld_left (expr
));
12611 /* Prepare expression for reading and writing.
12613 Like ffecom_prepare_expr, except for expressions to be evaluated
12614 via ffecom_expr_rw. */
12617 ffecom_prepare_expr_rw (tree type
, ffebld expr
)
12619 /* This is all we support for now. */
12620 assert (type
== NULL_TREE
|| type
== ffecom_type_expr (expr
));
12622 /* ~~For now, it seems to be the same thing. */
12623 ffecom_prepare_expr (expr
);
12627 /* Prepare expression for writing.
12629 Like ffecom_prepare_expr, except for expressions to be evaluated
12630 via ffecom_expr_w. */
12633 ffecom_prepare_expr_w (tree type
, ffebld expr
)
12635 /* This is all we support for now. */
12636 assert (type
== NULL_TREE
|| type
== ffecom_type_expr (expr
));
12638 /* ~~For now, it seems to be the same thing. */
12639 ffecom_prepare_expr (expr
);
12643 /* Prepare expression for returning.
12645 Like ffecom_prepare_expr, except for expressions to be evaluated
12646 via ffecom_return_expr. */
12649 ffecom_prepare_return_expr (ffebld expr
)
12651 assert (current_binding_level
->prep_state
< 2);
12653 if (ffecom_primary_entry_kind_
== FFEINFO_kindSUBROUTINE
12654 && ffecom_is_altreturning_
12656 ffecom_prepare_expr (expr
);
12659 /* Prepare pointer to expression.
12661 Like ffecom_prepare_expr, except for expressions to be evaluated
12662 via ffecom_ptr_to_expr. */
12665 ffecom_prepare_ptr_to_expr (ffebld expr
)
12667 /* ~~For now, it seems to be the same thing. */
12668 ffecom_prepare_expr (expr
);
12672 /* Transform expression into constant pointer-to-expression tree.
12674 If the expression can be transformed into a pointer-to-expression tree
12675 that is constant, that is done, and the tree returned. Else NULL_TREE
12678 That way, a caller can attempt to provide compile-time initialization
12679 of a variable and, if that fails, *then* choose to start a new block
12680 and resort to using temporaries, as appropriate. */
12683 ffecom_ptr_to_const_expr (ffebld expr
)
12686 return integer_zero_node
;
12688 if (ffebld_op (expr
) == FFEBLD_opANY
)
12689 return error_mark_node
;
12691 if (ffebld_arity (expr
) == 0
12692 && (ffebld_op (expr
) != FFEBLD_opSYMTER
12693 || ffebld_where (expr
) == FFEINFO_whereCOMMON
12694 || ffebld_where (expr
) == FFEINFO_whereGLOBAL
12695 || ffebld_where (expr
) == FFEINFO_whereINTRINSIC
))
12699 t
= ffecom_ptr_to_expr (expr
);
12700 assert (TREE_CONSTANT (t
));
12707 /* ffecom_return_expr -- Returns return-value expr given alt return expr
12709 tree rtn; // NULL_TREE means use expand_null_return()
12710 ffebld expr; // NULL if no alt return expr to RETURN stmt
12711 rtn = ffecom_return_expr(expr);
12713 Based on the program unit type and other info (like return function
12714 type, return master function type when alternate ENTRY points,
12715 whether subroutine has any alternate RETURN points, etc), returns the
12716 appropriate expression to be returned to the caller, or NULL_TREE
12717 meaning no return value or the caller expects it to be returned somewhere
12718 else (which is handled by other parts of this module). */
12721 ffecom_return_expr (ffebld expr
)
12725 switch (ffecom_primary_entry_kind_
)
12727 case FFEINFO_kindPROGRAM
:
12728 case FFEINFO_kindBLOCKDATA
:
12732 case FFEINFO_kindSUBROUTINE
:
12733 if (!ffecom_is_altreturning_
)
12734 rtn
= NULL_TREE
; /* No alt returns, never an expr. */
12735 else if (expr
== NULL
)
12736 rtn
= integer_zero_node
;
12738 rtn
= ffecom_expr (expr
);
12741 case FFEINFO_kindFUNCTION
:
12742 if ((ffecom_multi_retval_
!= NULL_TREE
)
12743 || (ffesymbol_basictype (ffecom_primary_entry_
)
12744 == FFEINFO_basictypeCHARACTER
)
12745 || ((ffesymbol_basictype (ffecom_primary_entry_
)
12746 == FFEINFO_basictypeCOMPLEX
)
12747 && (ffecom_num_entrypoints_
== 0)
12748 && ffesymbol_is_f2c (ffecom_primary_entry_
)))
12749 { /* Value is returned by direct assignment
12750 into (implicit) dummy. */
12754 rtn
= ffecom_func_result_
;
12756 /* Spurious error if RETURN happens before first reference! So elide
12757 this code. In particular, for debugging registry, rtn should always
12758 be non-null after all, but TREE_USED won't be set until we encounter
12759 a reference in the code. Perfectly okay (but weird) code that,
12760 e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in
12761 this diagnostic for no reason. Have people use -O -Wuninitialized
12762 and leave it to the back end to find obviously weird cases. */
12764 /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid
12765 situation; if the return value has never been referenced, it won't
12766 have a tree under 2pass mode. */
12767 if ((rtn
== NULL_TREE
)
12768 || !TREE_USED (rtn
))
12770 ffebad_start (FFEBAD_RETURN_VALUE_UNSET
);
12771 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_
),
12772 ffesymbol_where_column (ffecom_primary_entry_
));
12773 ffebad_string (ffesymbol_text (ffesymbol_funcresult
12774 (ffecom_primary_entry_
)));
12781 assert ("bad unit kind" == NULL
);
12782 case FFEINFO_kindANY
:
12783 rtn
= error_mark_node
;
12790 /* Do save_expr only if tree is not error_mark_node. */
12793 ffecom_save_tree (tree t
)
12795 return save_expr (t
);
12798 /* Start a compound statement (block). */
12801 ffecom_start_compstmt (void)
12803 bison_rule_pushlevel_ ();
12806 /* Public entry point for front end to access start_decl. */
12809 ffecom_start_decl (tree decl
, bool is_initialized
)
12811 DECL_INITIAL (decl
) = is_initialized
? error_mark_node
: NULL_TREE
;
12812 return start_decl (decl
, FALSE
);
12815 /* ffecom_sym_commit -- Symbol's state being committed to reality
12818 ffecom_sym_commit(s);
12820 Does whatever the backend needs when a symbol is committed after having
12821 been backtrackable for a period of time. */
12824 ffecom_sym_commit (ffesymbol s UNUSED
)
12826 assert (!ffesymbol_retractable ());
12829 /* ffecom_sym_end_transition -- Perform end transition on all symbols
12831 ffecom_sym_end_transition();
12833 Does backend-specific stuff and also calls ffest_sym_end_transition
12834 to do the necessary FFE stuff.
12836 Backtracking is never enabled when this fn is called, so don't worry
12840 ffecom_sym_end_transition (ffesymbol s
)
12844 assert (!ffesymbol_retractable ());
12846 s
= ffest_sym_end_transition (s
);
12848 if ((ffesymbol_kind (s
) == FFEINFO_kindBLOCKDATA
)
12849 && (ffesymbol_where (s
) == FFEINFO_whereGLOBAL
))
12851 ffecom_list_blockdata_
12852 = ffebld_new_item (ffebld_new_symter (s
, FFEINTRIN_genNONE
,
12853 FFEINTRIN_specNONE
,
12854 FFEINTRIN_impNONE
),
12855 ffecom_list_blockdata_
);
12858 /* This is where we finally notice that a symbol has partial initialization
12859 and finalize it. */
12861 if (ffesymbol_accretion (s
) != NULL
)
12863 assert (ffesymbol_init (s
) == NULL
);
12864 ffecom_notify_init_symbol (s
);
12866 else if (((st
= ffesymbol_storage (s
)) != NULL
)
12867 && ((st
= ffestorag_parent (st
)) != NULL
)
12868 && (ffestorag_accretion (st
) != NULL
))
12870 assert (ffestorag_init (st
) == NULL
);
12871 ffecom_notify_init_storage (st
);
12874 if ((ffesymbol_kind (s
) == FFEINFO_kindCOMMON
)
12875 && (ffesymbol_where (s
) == FFEINFO_whereLOCAL
)
12876 && (ffesymbol_storage (s
) != NULL
))
12878 ffecom_list_common_
12879 = ffebld_new_item (ffebld_new_symter (s
, FFEINTRIN_genNONE
,
12880 FFEINTRIN_specNONE
,
12881 FFEINTRIN_impNONE
),
12882 ffecom_list_common_
);
12888 /* ffecom_sym_exec_transition -- Perform exec transition on all symbols
12890 ffecom_sym_exec_transition();
12892 Does backend-specific stuff and also calls ffest_sym_exec_transition
12893 to do the necessary FFE stuff.
12895 See the long-winded description in ffecom_sym_learned for info
12896 on handling the situation where backtracking is inhibited. */
12899 ffecom_sym_exec_transition (ffesymbol s
)
12901 s
= ffest_sym_exec_transition (s
);
12906 /* ffecom_sym_learned -- Initial or more info gained on symbol after exec
12909 s = ffecom_sym_learned(s);
12911 Called when a new symbol is seen after the exec transition or when more
12912 info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when
12913 it arrives here is that all its latest info is updated already, so its
12914 state may be UNCERTAIN or UNDERSTOOD, it might already have the hook
12915 field filled in if its gone through here or exec_transition first, and
12918 The backend probably wants to check ffesymbol_retractable() to see if
12919 backtracking is in effect. If so, the FFE's changes to the symbol may
12920 be retracted (undone) or committed (ratified), at which time the
12921 appropriate ffecom_sym_retract or _commit function will be called
12924 If the backend has its own backtracking mechanism, great, use it so that
12925 committal is a simple operation. Though it doesn't make much difference,
12926 I suppose: the reason for tentative symbol evolution in the FFE is to
12927 enable error detection in weird incorrect statements early and to disable
12928 incorrect error detection on a correct statement. The backend is not
12929 likely to introduce any information that'll get involved in these
12930 considerations, so it is probably just fine that the implementation
12931 model for this fn and for _exec_transition is to not do anything
12932 (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE
12933 and instead wait until ffecom_sym_commit is called (which it never
12934 will be as long as we're using ambiguity-detecting statement analysis in
12935 the FFE, which we are initially to shake out the code, but don't depend
12936 on this), otherwise go ahead and do whatever is needed.
12938 In essence, then, when this fn and _exec_transition get called while
12939 backtracking is enabled, a general mechanism would be to flag which (or
12940 both) of these were called (and in what order? neat question as to what
12941 might happen that I'm too lame to think through right now) and then when
12942 _commit is called reproduce the original calling sequence, if any, for
12943 the two fns (at which point backtracking will, of course, be disabled). */
12946 ffecom_sym_learned (ffesymbol s
)
12948 ffestorag_exec_layout (s
);
12953 /* ffecom_sym_retract -- Symbol's state being retracted from reality
12956 ffecom_sym_retract(s);
12958 Does whatever the backend needs when a symbol is retracted after having
12959 been backtrackable for a period of time. */
12962 ffecom_sym_retract (ffesymbol s UNUSED
)
12964 assert (!ffesymbol_retractable ());
12966 #if 0 /* GCC doesn't commit any backtrackable sins,
12967 so nothing needed here. */
12968 switch (ffesymbol_hook (s
).state
)
12970 case 0: /* nothing happened yet. */
12973 case 1: /* exec transition happened. */
12976 case 2: /* learned happened. */
12979 case 3: /* learned then exec. */
12982 case 4: /* exec then learned. */
12986 assert ("bad hook state" == NULL
);
12992 /* Create temporary gcc label. */
12995 ffecom_temp_label ()
12998 static int mynumber
= 0;
13000 glabel
= build_decl (LABEL_DECL
,
13001 ffecom_get_invented_identifier ("__g77_label_%d",
13004 DECL_CONTEXT (glabel
) = current_function_decl
;
13005 DECL_MODE (glabel
) = VOIDmode
;
13010 /* Return an expression that is usable as an arg in a conditional context
13011 (IF, DO WHILE, .NOT., and so on).
13013 Use the one provided for the back end as of >2.6.0. */
13016 ffecom_truth_value (tree expr
)
13018 return ffe_truthvalue_conversion (expr
);
13021 /* Return the inversion of a truth value (the inversion of what
13022 ffecom_truth_value builds).
13024 Apparently invert_truthvalue, which is properly in the back end, is
13025 enough for now, so just use it. */
13028 ffecom_truth_value_invert (tree expr
)
13030 return invert_truthvalue (ffecom_truth_value (expr
));
13033 /* Return the tree that is the type of the expression, as would be
13034 returned in TREE_TYPE(ffecom_expr(expr)), without otherwise
13035 transforming the expression, generating temporaries, etc. */
13038 ffecom_type_expr (ffebld expr
)
13040 ffeinfoBasictype bt
;
13041 ffeinfoKindtype kt
;
13044 assert (expr
!= NULL
);
13046 bt
= ffeinfo_basictype (ffebld_info (expr
));
13047 kt
= ffeinfo_kindtype (ffebld_info (expr
));
13048 tree_type
= ffecom_tree_type
[bt
][kt
];
13050 switch (ffebld_op (expr
))
13052 case FFEBLD_opCONTER
:
13053 case FFEBLD_opSYMTER
:
13054 case FFEBLD_opARRAYREF
:
13055 case FFEBLD_opUPLUS
:
13056 case FFEBLD_opPAREN
:
13057 case FFEBLD_opUMINUS
:
13059 case FFEBLD_opSUBTRACT
:
13060 case FFEBLD_opMULTIPLY
:
13061 case FFEBLD_opDIVIDE
:
13062 case FFEBLD_opPOWER
:
13064 case FFEBLD_opFUNCREF
:
13065 case FFEBLD_opSUBRREF
:
13069 case FFEBLD_opNEQV
:
13071 case FFEBLD_opCONVERT
:
13078 case FFEBLD_opPERCENT_LOC
:
13081 case FFEBLD_opACCTER
:
13082 case FFEBLD_opARRTER
:
13083 case FFEBLD_opITEM
:
13084 case FFEBLD_opSTAR
:
13085 case FFEBLD_opBOUNDS
:
13086 case FFEBLD_opREPEAT
:
13087 case FFEBLD_opLABTER
:
13088 case FFEBLD_opLABTOK
:
13089 case FFEBLD_opIMPDO
:
13090 case FFEBLD_opCONCATENATE
:
13091 case FFEBLD_opSUBSTR
:
13093 assert ("bad op for ffecom_type_expr" == NULL
);
13094 /* Fall through. */
13096 return error_mark_node
;
13100 /* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points
13102 If the PARM_DECL already exists, return it, else create it. It's an
13103 integer_type_node argument for the master function that implements a
13104 subroutine or function with more than one entrypoint and is bound at
13105 run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for
13106 first ENTRY statement, and so on). */
13109 ffecom_which_entrypoint_decl ()
13111 assert (ffecom_which_entrypoint_decl_
!= NULL_TREE
);
13113 return ffecom_which_entrypoint_decl_
;
13116 /* The following sections consists of private and public functions
13117 that have the same names and perform roughly the same functions
13118 as counterparts in the C front end. Changes in the C front end
13119 might affect how things should be done here. Only functions
13120 needed by the back end should be public here; the rest should
13121 be private (static in the C sense). Functions needed by other
13122 g77 front-end modules should be accessed by them via public
13123 ffecom_* names, which should themselves call private versions
13124 in this section so the private versions are easy to recognize
13125 when upgrading to a new gcc and finding interesting changes
13128 Functions named after rule "foo:" in c-parse.y are named
13129 "bison_rule_foo_" so they are easy to find. */
13132 bison_rule_pushlevel_ ()
13134 emit_line_note (input_filename
, input_line
);
13136 clear_last_expr ();
13137 expand_start_bindings (0);
13141 bison_rule_compstmt_ ()
13144 int keep
= kept_level_p ();
13146 /* Make the temps go away. */
13148 current_binding_level
->names
= NULL_TREE
;
13150 emit_line_note (input_filename
, input_line
);
13151 expand_end_bindings (getdecls (), keep
, 0);
13152 t
= poplevel (keep
, 1, 0);
13157 /* Return a definition for a builtin function named NAME and whose data type
13158 is TYPE. TYPE should be a function type with argument types.
13159 FUNCTION_CODE tells later passes how to compile calls to this function.
13160 See tree.h for its possible values.
13162 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
13163 the name to be called if we can't opencode the function. If
13164 ATTRS is nonzero, use that for the function's attribute list. */
13167 builtin_function (const char *name
, tree type
, int function_code
,
13168 enum built_in_class
class,
13169 const char *library_name
,
13170 tree attrs ATTRIBUTE_UNUSED
)
13172 tree decl
= build_decl (FUNCTION_DECL
, get_identifier (name
), type
);
13173 DECL_EXTERNAL (decl
) = 1;
13174 TREE_PUBLIC (decl
) = 1;
13176 SET_DECL_ASSEMBLER_NAME (decl
, get_identifier (library_name
));
13177 make_decl_rtl (decl
, NULL
);
13179 DECL_BUILT_IN_CLASS (decl
) = class;
13180 DECL_FUNCTION_CODE (decl
) = function_code
;
13185 /* Handle when a new declaration NEWDECL
13186 has the same name as an old one OLDDECL
13187 in the same binding contour.
13188 Prints an error message if appropriate.
13190 If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
13191 Otherwise, return 0. */
13194 duplicate_decls (tree newdecl
, tree olddecl
)
13196 int types_match
= 1;
13197 int new_is_definition
= (TREE_CODE (newdecl
) == FUNCTION_DECL
13198 && DECL_INITIAL (newdecl
) != 0);
13199 tree oldtype
= TREE_TYPE (olddecl
);
13200 tree newtype
= TREE_TYPE (newdecl
);
13202 if (olddecl
== newdecl
)
13205 if (TREE_CODE (newtype
) == ERROR_MARK
13206 || TREE_CODE (oldtype
) == ERROR_MARK
)
13209 /* New decl is completely inconsistent with the old one =>
13210 tell caller to replace the old one.
13211 This is always an error except in the case of shadowing a builtin. */
13212 if (TREE_CODE (olddecl
) != TREE_CODE (newdecl
))
13215 /* For real parm decl following a forward decl,
13216 return 1 so old decl will be reused. */
13217 if (types_match
&& TREE_CODE (newdecl
) == PARM_DECL
13218 && TREE_ASM_WRITTEN (olddecl
) && ! TREE_ASM_WRITTEN (newdecl
))
13221 /* The new declaration is the same kind of object as the old one.
13222 The declarations may partially match. Print warnings if they don't
13223 match enough. Ultimately, copy most of the information from the new
13224 decl to the old one, and keep using the old one. */
13226 if (TREE_CODE (olddecl
) == FUNCTION_DECL
13227 && DECL_BUILT_IN (olddecl
))
13229 /* A function declaration for a built-in function. */
13230 if (!TREE_PUBLIC (newdecl
))
13232 else if (!types_match
)
13234 /* Accept the return type of the new declaration if same modes. */
13235 tree oldreturntype
= TREE_TYPE (TREE_TYPE (olddecl
));
13236 tree newreturntype
= TREE_TYPE (TREE_TYPE (newdecl
));
13238 if (TYPE_MODE (oldreturntype
) == TYPE_MODE (newreturntype
))
13240 /* Function types may be shared, so we can't just modify
13241 the return type of olddecl's function type. */
13243 = build_function_type (newreturntype
,
13244 TYPE_ARG_TYPES (TREE_TYPE (olddecl
)));
13248 TREE_TYPE (olddecl
) = newtype
;
13254 else if (TREE_CODE (olddecl
) == FUNCTION_DECL
13255 && DECL_SOURCE_LINE (olddecl
) == 0)
13257 /* A function declaration for a predeclared function
13258 that isn't actually built in. */
13259 if (!TREE_PUBLIC (newdecl
))
13261 else if (!types_match
)
13263 /* If the types don't match, preserve volatility indication.
13264 Later on, we will discard everything else about the
13265 default declaration. */
13266 TREE_THIS_VOLATILE (newdecl
) |= TREE_THIS_VOLATILE (olddecl
);
13270 /* Copy all the DECL_... slots specified in the new decl
13271 except for any that we copy here from the old type.
13273 Past this point, we don't change OLDTYPE and NEWTYPE
13274 even if we change the types of NEWDECL and OLDDECL. */
13278 /* Merge the data types specified in the two decls. */
13279 if (TREE_CODE (newdecl
) != FUNCTION_DECL
|| !DECL_BUILT_IN (olddecl
))
13280 TREE_TYPE (newdecl
)
13281 = TREE_TYPE (olddecl
)
13282 = TREE_TYPE (newdecl
);
13284 /* Lay the type out, unless already done. */
13285 if (oldtype
!= TREE_TYPE (newdecl
))
13287 if (TREE_TYPE (newdecl
) != error_mark_node
)
13288 layout_type (TREE_TYPE (newdecl
));
13289 if (TREE_CODE (newdecl
) != FUNCTION_DECL
13290 && TREE_CODE (newdecl
) != TYPE_DECL
13291 && TREE_CODE (newdecl
) != CONST_DECL
)
13292 layout_decl (newdecl
, 0);
13296 /* Since the type is OLDDECL's, make OLDDECL's size go with. */
13297 DECL_SIZE (newdecl
) = DECL_SIZE (olddecl
);
13298 DECL_SIZE_UNIT (newdecl
) = DECL_SIZE_UNIT (olddecl
);
13299 if (TREE_CODE (olddecl
) != FUNCTION_DECL
)
13300 if (DECL_ALIGN (olddecl
) > DECL_ALIGN (newdecl
))
13302 DECL_ALIGN (newdecl
) = DECL_ALIGN (olddecl
);
13303 DECL_USER_ALIGN (newdecl
) |= DECL_USER_ALIGN (olddecl
);
13307 /* Keep the old rtl since we can safely use it. */
13308 COPY_DECL_RTL (olddecl
, newdecl
);
13310 /* Merge the type qualifiers. */
13311 if (TREE_READONLY (newdecl
))
13312 TREE_READONLY (olddecl
) = 1;
13313 if (TREE_THIS_VOLATILE (newdecl
))
13315 TREE_THIS_VOLATILE (olddecl
) = 1;
13316 if (TREE_CODE (newdecl
) == VAR_DECL
)
13317 make_var_volatile (newdecl
);
13320 /* Keep source location of definition rather than declaration.
13321 Likewise, keep decl at outer scope. */
13322 if ((DECL_INITIAL (newdecl
) == 0 && DECL_INITIAL (olddecl
) != 0)
13323 || (DECL_CONTEXT (newdecl
) != 0 && DECL_CONTEXT (olddecl
) == 0))
13325 DECL_SOURCE_LINE (newdecl
) = DECL_SOURCE_LINE (olddecl
);
13326 DECL_SOURCE_FILE (newdecl
) = DECL_SOURCE_FILE (olddecl
);
13328 if (DECL_CONTEXT (olddecl
) == 0
13329 && TREE_CODE (newdecl
) != FUNCTION_DECL
)
13330 DECL_CONTEXT (newdecl
) = 0;
13333 /* Merge the unused-warning information. */
13334 if (DECL_IN_SYSTEM_HEADER (olddecl
))
13335 DECL_IN_SYSTEM_HEADER (newdecl
) = 1;
13336 else if (DECL_IN_SYSTEM_HEADER (newdecl
))
13337 DECL_IN_SYSTEM_HEADER (olddecl
) = 1;
13339 /* Merge the initialization information. */
13340 if (DECL_INITIAL (newdecl
) == 0)
13341 DECL_INITIAL (newdecl
) = DECL_INITIAL (olddecl
);
13343 /* Merge the section attribute.
13344 We want to issue an error if the sections conflict but that must be
13345 done later in decl_attributes since we are called before attributes
13347 if (DECL_SECTION_NAME (newdecl
) == NULL_TREE
)
13348 DECL_SECTION_NAME (newdecl
) = DECL_SECTION_NAME (olddecl
);
13350 /* Copy the assembler name. */
13351 COPY_DECL_ASSEMBLER_NAME (olddecl
, newdecl
);
13353 if (TREE_CODE (newdecl
) == FUNCTION_DECL
)
13355 DECL_STATIC_CONSTRUCTOR(newdecl
) |= DECL_STATIC_CONSTRUCTOR(olddecl
);
13356 DECL_STATIC_DESTRUCTOR (newdecl
) |= DECL_STATIC_DESTRUCTOR (olddecl
);
13357 TREE_THIS_VOLATILE (newdecl
) |= TREE_THIS_VOLATILE (olddecl
);
13358 TREE_READONLY (newdecl
) |= TREE_READONLY (olddecl
);
13359 DECL_IS_MALLOC (newdecl
) |= DECL_IS_MALLOC (olddecl
);
13360 DECL_IS_PURE (newdecl
) |= DECL_IS_PURE (olddecl
);
13363 /* If cannot merge, then use the new type and qualifiers,
13364 and don't preserve the old rtl. */
13367 TREE_TYPE (olddecl
) = TREE_TYPE (newdecl
);
13368 TREE_READONLY (olddecl
) = TREE_READONLY (newdecl
);
13369 TREE_THIS_VOLATILE (olddecl
) = TREE_THIS_VOLATILE (newdecl
);
13370 TREE_SIDE_EFFECTS (olddecl
) = TREE_SIDE_EFFECTS (newdecl
);
13373 /* Merge the storage class information. */
13374 /* For functions, static overrides non-static. */
13375 if (TREE_CODE (newdecl
) == FUNCTION_DECL
)
13377 TREE_PUBLIC (newdecl
) &= TREE_PUBLIC (olddecl
);
13378 /* This is since we don't automatically
13379 copy the attributes of NEWDECL into OLDDECL. */
13380 TREE_PUBLIC (olddecl
) = TREE_PUBLIC (newdecl
);
13381 /* If this clears `static', clear it in the identifier too. */
13382 if (! TREE_PUBLIC (olddecl
))
13383 TREE_PUBLIC (DECL_NAME (olddecl
)) = 0;
13385 if (DECL_EXTERNAL (newdecl
))
13387 TREE_STATIC (newdecl
) = TREE_STATIC (olddecl
);
13388 DECL_EXTERNAL (newdecl
) = DECL_EXTERNAL (olddecl
);
13389 /* An extern decl does not override previous storage class. */
13390 TREE_PUBLIC (newdecl
) = TREE_PUBLIC (olddecl
);
13394 TREE_STATIC (olddecl
) = TREE_STATIC (newdecl
);
13395 TREE_PUBLIC (olddecl
) = TREE_PUBLIC (newdecl
);
13398 /* If either decl says `inline', this fn is inline,
13399 unless its definition was passed already. */
13400 if (DECL_INLINE (newdecl
) && DECL_INITIAL (olddecl
) == 0)
13401 DECL_INLINE (olddecl
) = 1;
13402 DECL_INLINE (newdecl
) = DECL_INLINE (olddecl
);
13404 /* Get rid of any built-in function if new arg types don't match it
13405 or if we have a function definition. */
13406 if (TREE_CODE (newdecl
) == FUNCTION_DECL
13407 && DECL_BUILT_IN (olddecl
)
13408 && (!types_match
|| new_is_definition
))
13410 TREE_TYPE (olddecl
) = TREE_TYPE (newdecl
);
13411 DECL_BUILT_IN_CLASS (olddecl
) = NOT_BUILT_IN
;
13414 /* If redeclaring a builtin function, and not a definition,
13416 Also preserve various other info from the definition. */
13417 if (TREE_CODE (newdecl
) == FUNCTION_DECL
&& !new_is_definition
)
13419 if (DECL_BUILT_IN (olddecl
))
13421 DECL_BUILT_IN_CLASS (newdecl
) = DECL_BUILT_IN_CLASS (olddecl
);
13422 DECL_FUNCTION_CODE (newdecl
) = DECL_FUNCTION_CODE (olddecl
);
13425 DECL_RESULT (newdecl
) = DECL_RESULT (olddecl
);
13426 DECL_INITIAL (newdecl
) = DECL_INITIAL (olddecl
);
13427 DECL_SAVED_INSNS (newdecl
) = DECL_SAVED_INSNS (olddecl
);
13428 DECL_ARGUMENTS (newdecl
) = DECL_ARGUMENTS (olddecl
);
13431 /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
13432 But preserve olddecl's DECL_UID. */
13434 register unsigned olddecl_uid
= DECL_UID (olddecl
);
13436 memcpy ((char *) olddecl
+ sizeof (struct tree_common
),
13437 (char *) newdecl
+ sizeof (struct tree_common
),
13438 sizeof (struct tree_decl
) - sizeof (struct tree_common
));
13439 DECL_UID (olddecl
) = olddecl_uid
;
13445 /* Finish processing of a declaration;
13446 install its initial value.
13447 If the length of an array type is not known before,
13448 it must be determined now, from the initial value, or it is an error. */
13451 finish_decl (tree decl
, tree init
, bool is_top_level
)
13453 register tree type
= TREE_TYPE (decl
);
13454 int was_incomplete
= (DECL_SIZE (decl
) == 0);
13455 bool at_top_level
= (current_binding_level
== global_binding_level
);
13456 bool top_level
= is_top_level
|| at_top_level
;
13458 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13460 assert (!is_top_level
|| !at_top_level
);
13462 if (TREE_CODE (decl
) == PARM_DECL
)
13463 assert (init
== NULL_TREE
);
13464 /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it
13465 overlaps DECL_ARG_TYPE. */
13466 else if (init
== NULL_TREE
)
13467 assert (DECL_INITIAL (decl
) == NULL_TREE
);
13469 assert (DECL_INITIAL (decl
) == error_mark_node
);
13471 if (init
!= NULL_TREE
)
13473 if (TREE_CODE (decl
) != TYPE_DECL
)
13474 DECL_INITIAL (decl
) = init
;
13477 /* typedef foo = bar; store the type of bar as the type of foo. */
13478 TREE_TYPE (decl
) = TREE_TYPE (init
);
13479 DECL_INITIAL (decl
) = init
= 0;
13483 /* Deduce size of array from initialization, if not already known */
13485 if (TREE_CODE (type
) == ARRAY_TYPE
13486 && TYPE_DOMAIN (type
) == 0
13487 && TREE_CODE (decl
) != TYPE_DECL
)
13489 assert (top_level
);
13490 assert (was_incomplete
);
13492 layout_decl (decl
, 0);
13495 if (TREE_CODE (decl
) == VAR_DECL
)
13497 if (DECL_SIZE (decl
) == NULL_TREE
13498 && TYPE_SIZE (TREE_TYPE (decl
)) != NULL_TREE
)
13499 layout_decl (decl
, 0);
13501 if (DECL_SIZE (decl
) == NULL_TREE
13502 && (TREE_STATIC (decl
)
13504 /* A static variable with an incomplete type is an error if it is
13505 initialized. Also if it is not file scope. Otherwise, let it
13506 through, but if it is not `extern' then it may cause an error
13508 (DECL_INITIAL (decl
) != 0 || DECL_CONTEXT (decl
) != 0)
13510 /* An automatic variable with an incomplete type is an error. */
13511 !DECL_EXTERNAL (decl
)))
13513 assert ("storage size not known" == NULL
);
13517 if ((DECL_EXTERNAL (decl
) || TREE_STATIC (decl
))
13518 && (DECL_SIZE (decl
) != 0)
13519 && (TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
))
13521 assert ("storage size not constant" == NULL
);
13526 /* Output the assembler code and/or RTL code for variables and functions,
13527 unless the type is an undefined structure or union. If not, it will get
13528 done when the type is completed. */
13530 if (TREE_CODE (decl
) == VAR_DECL
|| TREE_CODE (decl
) == FUNCTION_DECL
)
13532 rest_of_decl_compilation (decl
, NULL
,
13533 DECL_CONTEXT (decl
) == 0,
13536 if (DECL_CONTEXT (decl
) != 0)
13538 /* Recompute the RTL of a local array now if it used to be an
13539 incomplete type. */
13541 && !TREE_STATIC (decl
) && !DECL_EXTERNAL (decl
))
13543 /* If we used it already as memory, it must stay in memory. */
13544 TREE_ADDRESSABLE (decl
) = TREE_USED (decl
);
13545 /* If it's still incomplete now, no init will save it. */
13546 if (DECL_SIZE (decl
) == 0)
13547 DECL_INITIAL (decl
) = 0;
13548 expand_decl (decl
);
13550 /* Compute and store the initial value. */
13551 if (TREE_CODE (decl
) != FUNCTION_DECL
)
13552 expand_decl_init (decl
);
13555 else if (TREE_CODE (decl
) == TYPE_DECL
)
13557 rest_of_decl_compilation (decl
, NULL
,
13558 DECL_CONTEXT (decl
) == 0,
13562 /* At the end of a declaration, throw away any variable type sizes of types
13563 defined inside that declaration. There is no use computing them in the
13564 following function definition. */
13565 if (current_binding_level
== global_binding_level
)
13566 get_pending_sizes ();
13569 /* Finish up a function declaration and compile that function
13570 all the way to assembler language output. The free the storage
13571 for the function definition.
13573 This is called after parsing the body of the function definition.
13575 NESTED is nonzero if the function being finished is nested in another. */
13578 finish_function (int nested
)
13580 register tree fndecl
= current_function_decl
;
13582 assert (fndecl
!= NULL_TREE
);
13583 if (TREE_CODE (fndecl
) != ERROR_MARK
)
13586 assert (DECL_CONTEXT (fndecl
) != NULL_TREE
);
13588 assert (DECL_CONTEXT (fndecl
) == NULL_TREE
);
13591 /* TREE_READONLY (fndecl) = 1;
13592 This caused &foo to be of type ptr-to-const-function
13593 which then got a warning when stored in a ptr-to-function variable. */
13595 poplevel (1, 0, 1);
13597 if (TREE_CODE (fndecl
) != ERROR_MARK
)
13599 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl
)) = fndecl
;
13601 /* Must mark the RESULT_DECL as being in this function. */
13603 DECL_CONTEXT (DECL_RESULT (fndecl
)) = fndecl
;
13605 /* Obey `register' declarations if `setjmp' is called in this fn. */
13606 /* Generate rtl for function exit. */
13607 expand_function_end (input_filename
, input_line
, 0);
13609 /* If this is a nested function, protect the local variables in the stack
13610 above us from being collected while we're compiling this function. */
13612 ggc_push_context ();
13614 /* Run the optimizers and output the assembler code for this function. */
13615 rest_of_compilation (fndecl
);
13617 /* Undo the GC context switch. */
13619 ggc_pop_context ();
13622 if (TREE_CODE (fndecl
) != ERROR_MARK
13624 && DECL_SAVED_INSNS (fndecl
) == 0)
13626 /* Stop pointing to the local nodes about to be freed. */
13627 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13628 function definition. */
13629 /* For a nested function, this is done in pop_f_function_context. */
13630 /* If rest_of_compilation set this to 0, leave it 0. */
13631 if (DECL_INITIAL (fndecl
) != 0)
13632 DECL_INITIAL (fndecl
) = error_mark_node
;
13633 DECL_ARGUMENTS (fndecl
) = 0;
13638 /* Let the error reporting routines know that we're outside a function.
13639 For a nested function, this value is used in pop_c_function_context
13640 and then reset via pop_function_context. */
13641 ffecom_outer_function_decl_
= current_function_decl
= NULL
;
13645 /* Plug-in replacement for identifying the name of a decl and, for a
13646 function, what we call it in diagnostics. For now, "program unit"
13647 should suffice, since it's a bit of a hassle to figure out which
13648 of several kinds of things it is. Note that it could conceivably
13649 be a statement function, which probably isn't really a program unit
13650 per se, but if that comes up, it should be easy to check (being a
13651 nested function and all). */
13653 static const char *
13654 ffe_printable_name (tree decl
, int v
)
13656 /* Just to keep GCC quiet about the unused variable.
13657 In theory, differing values of V should produce different
13662 if (TREE_CODE (decl
) == ERROR_MARK
)
13663 return "erroneous code";
13664 return IDENTIFIER_POINTER (DECL_NAME (decl
));
13668 /* g77's function to print out name of current function that caused
13672 ffe_print_error_function (diagnostic_context
*context
__attribute__((unused
)),
13675 static ffeglobal last_g
= NULL
;
13676 static ffesymbol last_s
= NULL
;
13681 if ((ffecom_primary_entry_
== NULL
)
13682 || (ffesymbol_global (ffecom_primary_entry_
) == NULL
))
13690 g
= ffesymbol_global (ffecom_primary_entry_
);
13691 if (ffecom_nested_entry_
== NULL
)
13693 s
= ffecom_primary_entry_
;
13694 kind
= _(ffeinfo_kind_message (ffesymbol_kind (s
)));
13698 s
= ffecom_nested_entry_
;
13699 kind
= _("In statement function");
13703 if ((last_g
!= g
) || (last_s
!= s
))
13706 fprintf (stderr
, "%s: ", file
);
13709 fprintf (stderr
, _("Outside of any program unit:\n"));
13712 const char *name
= ffesymbol_text (s
);
13714 fprintf (stderr
, "%s `%s':\n", kind
, name
);
13722 /* Similar to `lookup_name' but look only at current binding level. */
13725 lookup_name_current_level (tree name
)
13729 if (current_binding_level
== global_binding_level
)
13730 return IDENTIFIER_GLOBAL_VALUE (name
);
13732 if (IDENTIFIER_LOCAL_VALUE (name
) == 0)
13735 for (t
= current_binding_level
->names
; t
; t
= TREE_CHAIN (t
))
13736 if (DECL_NAME (t
) == name
)
13742 /* Create a new `struct f_binding_level'. */
13744 static struct f_binding_level
*
13745 make_binding_level ()
13748 return ggc_alloc (sizeof (struct f_binding_level
));
13751 /* Save and restore the variables in this file and elsewhere
13752 that keep track of the progress of compilation of the current function.
13753 Used for nested functions. */
13757 struct f_function
*next
;
13759 tree shadowed_labels
;
13760 struct f_binding_level
*binding_level
;
13763 struct f_function
*f_function_chain
;
13765 /* Restore the variables used during compilation of a C function. */
13768 pop_f_function_context ()
13770 struct f_function
*p
= f_function_chain
;
13773 /* Bring back all the labels that were shadowed. */
13774 for (link
= shadowed_labels
; link
; link
= TREE_CHAIN (link
))
13775 if (DECL_NAME (TREE_VALUE (link
)) != 0)
13776 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link
)))
13777 = TREE_VALUE (link
);
13779 if (current_function_decl
!= error_mark_node
13780 && DECL_SAVED_INSNS (current_function_decl
) == 0)
13782 /* Stop pointing to the local nodes about to be freed. */
13783 /* But DECL_INITIAL must remain nonzero so we know this was an actual
13784 function definition. */
13785 DECL_INITIAL (current_function_decl
) = error_mark_node
;
13786 DECL_ARGUMENTS (current_function_decl
) = 0;
13789 pop_function_context ();
13791 f_function_chain
= p
->next
;
13793 named_labels
= p
->named_labels
;
13794 shadowed_labels
= p
->shadowed_labels
;
13795 current_binding_level
= p
->binding_level
;
13800 /* Save and reinitialize the variables
13801 used during compilation of a C function. */
13804 push_f_function_context ()
13806 struct f_function
*p
13807 = (struct f_function
*) xmalloc (sizeof (struct f_function
));
13809 push_function_context ();
13811 p
->next
= f_function_chain
;
13812 f_function_chain
= p
;
13814 p
->named_labels
= named_labels
;
13815 p
->shadowed_labels
= shadowed_labels
;
13816 p
->binding_level
= current_binding_level
;
13820 push_parm_decl (tree parm
)
13822 int old_immediate_size_expand
= immediate_size_expand
;
13824 /* Don't try computing parm sizes now -- wait till fn is called. */
13826 immediate_size_expand
= 0;
13828 /* Fill in arg stuff. */
13830 DECL_ARG_TYPE (parm
) = TREE_TYPE (parm
);
13831 DECL_ARG_TYPE_AS_WRITTEN (parm
) = TREE_TYPE (parm
);
13832 TREE_READONLY (parm
) = 1; /* All implementation args are read-only. */
13834 parm
= pushdecl (parm
);
13836 immediate_size_expand
= old_immediate_size_expand
;
13838 finish_decl (parm
, NULL_TREE
, FALSE
);
13841 /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
13844 pushdecl_top_level (tree x
)
13847 register struct f_binding_level
*b
= current_binding_level
;
13848 register tree f
= current_function_decl
;
13850 current_binding_level
= global_binding_level
;
13851 current_function_decl
= NULL_TREE
;
13853 current_binding_level
= b
;
13854 current_function_decl
= f
;
13858 /* Store the list of declarations of the current level.
13859 This is done for the parameter declarations of a function being defined,
13860 after they are modified in the light of any missing parameters. */
13863 storedecls (tree decls
)
13865 return current_binding_level
->names
= decls
;
13868 /* Store the parameter declarations into the current function declaration.
13869 This is called after parsing the parameter declarations, before
13870 digesting the body of the function.
13872 For an old-style definition, modify the function's type
13873 to specify at least the number of arguments. */
13876 store_parm_decls (int is_main_program UNUSED
)
13878 register tree fndecl
= current_function_decl
;
13880 if (fndecl
== error_mark_node
)
13883 /* This is a chain of PARM_DECLs from old-style parm declarations. */
13884 DECL_ARGUMENTS (fndecl
) = storedecls (nreverse (getdecls ()));
13886 /* Initialize the RTL code for the function. */
13887 init_function_start (fndecl
);
13889 /* Set up parameters and prepare for return, for the function. */
13890 expand_function_start (fndecl
, 0);
13894 start_decl (tree decl
, bool is_top_level
)
13897 bool at_top_level
= (current_binding_level
== global_binding_level
);
13898 bool top_level
= is_top_level
|| at_top_level
;
13900 /* Caller should pass TRUE for is_top_level only if we wouldn't be at top
13902 assert (!is_top_level
|| !at_top_level
);
13904 if (DECL_INITIAL (decl
) != NULL_TREE
)
13906 assert (DECL_INITIAL (decl
) == error_mark_node
);
13907 assert (!DECL_EXTERNAL (decl
));
13909 else if (top_level
)
13910 assert ((TREE_STATIC (decl
) == 1) || DECL_EXTERNAL (decl
) == 1);
13912 /* For Fortran, we by default put things in .common when possible. */
13913 DECL_COMMON (decl
) = 1;
13915 /* Add this decl to the current binding level. TEM may equal DECL or it may
13916 be a previous decl of the same name. */
13918 tem
= pushdecl_top_level (decl
);
13920 tem
= pushdecl (decl
);
13922 /* For a local variable, define the RTL now. */
13924 /* But not if this is a duplicate decl and we preserved the rtl from the
13925 previous one (which may or may not happen). */
13926 && !DECL_RTL_SET_P (tem
))
13928 if (TYPE_SIZE (TREE_TYPE (tem
)) != 0)
13930 else if (TREE_CODE (TREE_TYPE (tem
)) == ARRAY_TYPE
13931 && DECL_INITIAL (tem
) != 0)
13938 /* Create the FUNCTION_DECL for a function definition.
13939 DECLSPECS and DECLARATOR are the parts of the declaration;
13940 they describe the function's name and the type it returns,
13941 but twisted together in a fashion that parallels the syntax of C.
13943 This function creates a binding context for the function body
13944 as well as setting up the FUNCTION_DECL in current_function_decl.
13946 Returns 1 on success. If the DECLARATOR is not suitable for a function
13947 (it defines a datum instead), we return 0, which tells
13948 ffe_parse_file to report a parse error.
13950 NESTED is nonzero for a function nested within another function. */
13953 start_function (tree name
, tree type
, int nested
, int public)
13957 int old_immediate_size_expand
= immediate_size_expand
;
13960 shadowed_labels
= 0;
13962 /* Don't expand any sizes in the return type of the function. */
13963 immediate_size_expand
= 0;
13968 assert (current_function_decl
!= NULL_TREE
);
13969 assert (DECL_CONTEXT (current_function_decl
) == NULL_TREE
);
13973 assert (current_function_decl
== NULL_TREE
);
13976 if (TREE_CODE (type
) == ERROR_MARK
)
13977 decl1
= current_function_decl
= error_mark_node
;
13980 decl1
= build_decl (FUNCTION_DECL
,
13983 TREE_PUBLIC (decl1
) = public ? 1 : 0;
13985 DECL_INLINE (decl1
) = 1;
13986 TREE_STATIC (decl1
) = 1;
13987 DECL_EXTERNAL (decl1
) = 0;
13989 announce_function (decl1
);
13991 /* Make the init_value nonzero so pushdecl knows this is not tentative.
13992 error_mark_node is replaced below (in poplevel) with the BLOCK. */
13993 DECL_INITIAL (decl1
) = error_mark_node
;
13995 /* Record the decl so that the function name is defined. If we already have
13996 a decl for this name, and it is a FUNCTION_DECL, use the old decl. */
13998 current_function_decl
= pushdecl (decl1
);
14002 ffecom_outer_function_decl_
= current_function_decl
;
14005 current_binding_level
->prep_state
= 2;
14007 if (TREE_CODE (current_function_decl
) != ERROR_MARK
)
14009 make_decl_rtl (current_function_decl
, NULL
);
14011 restype
= TREE_TYPE (TREE_TYPE (current_function_decl
));
14012 DECL_RESULT (current_function_decl
)
14013 = build_decl (RESULT_DECL
, NULL_TREE
, restype
);
14016 if (!nested
&& (TREE_CODE (current_function_decl
) != ERROR_MARK
))
14017 TREE_ADDRESSABLE (current_function_decl
) = 1;
14019 immediate_size_expand
= old_immediate_size_expand
;
14022 /* Here are the public functions the GNU back end needs. */
14025 convert (tree type
, tree expr
)
14027 register tree e
= expr
;
14028 register enum tree_code code
= TREE_CODE (type
);
14030 if (type
== TREE_TYPE (e
)
14031 || TREE_CODE (e
) == ERROR_MARK
)
14033 if (TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (TREE_TYPE (e
)))
14034 return fold (build1 (NOP_EXPR
, type
, e
));
14035 if (TREE_CODE (TREE_TYPE (e
)) == ERROR_MARK
14036 || code
== ERROR_MARK
)
14037 return error_mark_node
;
14038 if (TREE_CODE (TREE_TYPE (e
)) == VOID_TYPE
)
14040 assert ("void value not ignored as it ought to be" == NULL
);
14041 return error_mark_node
;
14043 if (code
== VOID_TYPE
)
14044 return build1 (CONVERT_EXPR
, type
, e
);
14045 if ((code
!= RECORD_TYPE
)
14046 && (TREE_CODE (TREE_TYPE (e
)) == RECORD_TYPE
))
14047 e
= ffecom_1 (REALPART_EXPR
, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e
))),
14049 if (code
== INTEGER_TYPE
|| code
== ENUMERAL_TYPE
)
14050 return fold (convert_to_integer (type
, e
));
14051 if (code
== POINTER_TYPE
)
14052 return fold (convert_to_pointer (type
, e
));
14053 if (code
== REAL_TYPE
)
14054 return fold (convert_to_real (type
, e
));
14055 if (code
== COMPLEX_TYPE
)
14056 return fold (convert_to_complex (type
, e
));
14057 if (code
== RECORD_TYPE
)
14058 return fold (ffecom_convert_to_complex_ (type
, e
));
14060 assert ("conversion to non-scalar type requested" == NULL
);
14061 return error_mark_node
;
14064 /* Return the list of declarations of the current level.
14065 Note that this list is in reverse order unless/until
14066 you nreverse it; and when you do nreverse it, you must
14067 store the result back using `storedecls' or you will lose. */
14072 return current_binding_level
->names
;
14075 /* Nonzero if we are currently in the global binding level. */
14078 global_bindings_p ()
14080 return current_binding_level
== global_binding_level
;
14084 ffecom_init_decl_processing ()
14091 /* Delete the node BLOCK from the current binding level.
14092 This is used for the block inside a stmt expr ({...})
14093 so that the block can be reinserted where appropriate. */
14096 delete_block (tree block
)
14099 if (current_binding_level
->blocks
== block
)
14100 current_binding_level
->blocks
= TREE_CHAIN (block
);
14101 for (t
= current_binding_level
->blocks
; t
;)
14103 if (TREE_CHAIN (t
) == block
)
14104 TREE_CHAIN (t
) = TREE_CHAIN (block
);
14106 t
= TREE_CHAIN (t
);
14108 TREE_CHAIN (block
) = NULL
;
14109 /* Clear TREE_USED which is always set by poplevel.
14110 The flag is set again if insert_block is called. */
14111 TREE_USED (block
) = 0;
14115 insert_block (tree block
)
14117 TREE_USED (block
) = 1;
14118 current_binding_level
->blocks
14119 = chainon (current_binding_level
->blocks
, block
);
14122 /* Each front end provides its own. */
14123 static bool ffe_init
PARAMS ((void));
14124 static void ffe_finish
PARAMS ((void));
14125 static bool ffe_post_options
PARAMS ((const char **));
14126 static void ffe_print_identifier
PARAMS ((FILE *, tree
, int));
14128 struct language_function
GTY(())
14133 #undef LANG_HOOKS_NAME
14134 #define LANG_HOOKS_NAME "GNU F77"
14135 #undef LANG_HOOKS_INIT
14136 #define LANG_HOOKS_INIT ffe_init
14137 #undef LANG_HOOKS_FINISH
14138 #define LANG_HOOKS_FINISH ffe_finish
14139 #undef LANG_HOOKS_INIT_OPTIONS
14140 #define LANG_HOOKS_INIT_OPTIONS ffe_init_options
14141 #undef LANG_HOOKS_HANDLE_OPTION
14142 #define LANG_HOOKS_HANDLE_OPTION ffe_handle_option
14143 #undef LANG_HOOKS_POST_OPTIONS
14144 #define LANG_HOOKS_POST_OPTIONS ffe_post_options
14145 #undef LANG_HOOKS_PARSE_FILE
14146 #define LANG_HOOKS_PARSE_FILE ffe_parse_file
14147 #undef LANG_HOOKS_MARK_ADDRESSABLE
14148 #define LANG_HOOKS_MARK_ADDRESSABLE ffe_mark_addressable
14149 #undef LANG_HOOKS_PRINT_IDENTIFIER
14150 #define LANG_HOOKS_PRINT_IDENTIFIER ffe_print_identifier
14151 #undef LANG_HOOKS_DECL_PRINTABLE_NAME
14152 #define LANG_HOOKS_DECL_PRINTABLE_NAME ffe_printable_name
14153 #undef LANG_HOOKS_PRINT_ERROR_FUNCTION
14154 #define LANG_HOOKS_PRINT_ERROR_FUNCTION ffe_print_error_function
14155 #undef LANG_HOOKS_TRUTHVALUE_CONVERSION
14156 #define LANG_HOOKS_TRUTHVALUE_CONVERSION ffe_truthvalue_conversion
14158 #undef LANG_HOOKS_TYPE_FOR_MODE
14159 #define LANG_HOOKS_TYPE_FOR_MODE ffe_type_for_mode
14160 #undef LANG_HOOKS_TYPE_FOR_SIZE
14161 #define LANG_HOOKS_TYPE_FOR_SIZE ffe_type_for_size
14162 #undef LANG_HOOKS_SIGNED_TYPE
14163 #define LANG_HOOKS_SIGNED_TYPE ffe_signed_type
14164 #undef LANG_HOOKS_UNSIGNED_TYPE
14165 #define LANG_HOOKS_UNSIGNED_TYPE ffe_unsigned_type
14166 #undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
14167 #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE ffe_signed_or_unsigned_type
14169 /* We do not wish to use alias-set based aliasing at all. Used in the
14170 extreme (every object with its own set, with equivalences recorded) it
14171 might be helpful, but there are problems when it comes to inlining. We
14172 get on ok with flag_argument_noalias, and alias-set aliasing does
14173 currently limit how stack slots can be reused, which is a lose. */
14174 #undef LANG_HOOKS_GET_ALIAS_SET
14175 #define LANG_HOOKS_GET_ALIAS_SET hook_get_alias_set_0
14177 const struct lang_hooks lang_hooks
= LANG_HOOKS_INITIALIZER
;
14179 /* Table indexed by tree code giving a string containing a character
14180 classifying the tree code. Possibilities are
14181 t, d, s, c, r, <, 1, 2 and e. See tree.def for details. */
14183 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
14185 const char tree_code_type
[] = {
14186 #include "tree.def"
14190 /* Table indexed by tree code giving number of expression
14191 operands beyond the fixed part of the node structure.
14192 Not used for types or decls. */
14194 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
14196 const unsigned char tree_code_length
[] = {
14197 #include "tree.def"
14201 /* Names of tree components.
14202 Used for printing out the tree and error messages. */
14203 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
14205 const char *const tree_code_name
[] = {
14206 #include "tree.def"
14211 ffe_post_options (pfilename
)
14212 const char **pfilename
;
14214 const char *filename
= *pfilename
;
14216 /* Open input file. */
14217 if (filename
== 0 || !strcmp (filename
, "-"))
14220 filename
= "stdin";
14223 finput
= fopen (filename
, "r");
14226 fatal_error ("can't open %s: %m", filename
);
14235 #ifdef IO_BUFFER_SIZE
14236 setvbuf (finput
, (char *) xmalloc (IO_BUFFER_SIZE
), _IOFBF
, IO_BUFFER_SIZE
);
14239 ffecom_init_decl_processing ();
14241 /* If the file is output from cpp, it should contain a first line
14242 `# 1 "real-filename"', and the current design of gcc (toplev.c
14243 in particular and the way it sets up information relied on by
14244 INCLUDE) requires that we read this now, and store the
14245 "real-filename" info in master_input_filename. Ask the lexer
14246 to try doing this. */
14247 ffelex_hash_kludge (finput
);
14249 /* FIXME: The ffelex_hash_kludge code needs to be cleaned up to
14250 set the new file name. Maybe in ffe_post_options. */
14257 ffe_terminate_0 ();
14259 if (ffe_is_ffedebug ())
14260 malloc_pool_display (malloc_pool_image ());
14266 ffe_mark_addressable (tree exp
)
14268 register tree x
= exp
;
14270 switch (TREE_CODE (x
))
14273 case COMPONENT_REF
:
14275 x
= TREE_OPERAND (x
, 0);
14279 TREE_ADDRESSABLE (x
) = 1;
14286 if (DECL_REGISTER (x
) && !TREE_ADDRESSABLE (x
)
14287 && DECL_NONLOCAL (x
))
14289 if (TREE_PUBLIC (x
))
14291 assert ("address of global register var requested" == NULL
);
14294 assert ("address of register variable requested" == NULL
);
14296 else if (DECL_REGISTER (x
) && !TREE_ADDRESSABLE (x
))
14298 if (TREE_PUBLIC (x
))
14300 assert ("address of global register var requested" == NULL
);
14303 assert ("address of register var requested" == NULL
);
14305 put_var_into_stack (x
, /*rescan=*/true);
14308 case FUNCTION_DECL
:
14309 TREE_ADDRESSABLE (x
) = 1;
14310 #if 0 /* poplevel deals with this now. */
14311 if (DECL_CONTEXT (x
) == 0)
14312 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x
)) = 1;
14320 /* Exit a binding level.
14321 Pop the level off, and restore the state of the identifier-decl mappings
14322 that were in effect when this level was entered.
14324 If KEEP is nonzero, this level had explicit declarations, so
14325 and create a "block" (a BLOCK node) for the level
14326 to record its declarations and subblocks for symbol table output.
14328 If FUNCTIONBODY is nonzero, this level is the body of a function,
14329 so create a block as if KEEP were set and also clear out all
14332 If REVERSE is nonzero, reverse the order of decls before putting
14333 them into the BLOCK. */
14336 poplevel (int keep
, int reverse
, int functionbody
)
14338 register tree link
;
14339 /* The chain of decls was accumulated in reverse order.
14340 Put it into forward order, just for cleanliness. */
14342 tree subblocks
= current_binding_level
->blocks
;
14345 int block_previously_created
;
14347 /* Get the decls in the order they were written.
14348 Usually current_binding_level->names is in reverse order.
14349 But parameter decls were previously put in forward order. */
14352 current_binding_level
->names
14353 = decls
= nreverse (current_binding_level
->names
);
14355 decls
= current_binding_level
->names
;
14357 /* Output any nested inline functions within this block
14358 if they weren't already output. */
14360 for (decl
= decls
; decl
; decl
= TREE_CHAIN (decl
))
14361 if (TREE_CODE (decl
) == FUNCTION_DECL
14362 && ! TREE_ASM_WRITTEN (decl
)
14363 && DECL_INITIAL (decl
) != 0
14364 && TREE_ADDRESSABLE (decl
))
14366 /* If this decl was copied from a file-scope decl
14367 on account of a block-scope extern decl,
14368 propagate TREE_ADDRESSABLE to the file-scope decl.
14370 DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
14371 true, since then the decl goes through save_for_inline_copying. */
14372 if (DECL_ABSTRACT_ORIGIN (decl
) != 0
14373 && DECL_ABSTRACT_ORIGIN (decl
) != decl
)
14374 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl
)) = 1;
14375 else if (DECL_SAVED_INSNS (decl
) != 0)
14377 push_function_context ();
14378 output_inline_function (decl
);
14379 pop_function_context ();
14383 /* If there were any declarations or structure tags in that level,
14384 or if this level is a function body,
14385 create a BLOCK to record them for the life of this function. */
14388 block_previously_created
= (current_binding_level
->this_block
!= 0);
14389 if (block_previously_created
)
14390 block
= current_binding_level
->this_block
;
14391 else if (keep
|| functionbody
)
14392 block
= make_node (BLOCK
);
14395 BLOCK_VARS (block
) = decls
;
14396 BLOCK_SUBBLOCKS (block
) = subblocks
;
14399 /* In each subblock, record that this is its superior. */
14401 for (link
= subblocks
; link
; link
= TREE_CHAIN (link
))
14402 BLOCK_SUPERCONTEXT (link
) = block
;
14404 /* Clear out the meanings of the local variables of this level. */
14406 for (link
= decls
; link
; link
= TREE_CHAIN (link
))
14408 if (DECL_NAME (link
) != 0)
14410 /* If the ident. was used or addressed via a local extern decl,
14411 don't forget that fact. */
14412 if (DECL_EXTERNAL (link
))
14414 if (TREE_USED (link
))
14415 TREE_USED (DECL_NAME (link
)) = 1;
14416 if (TREE_ADDRESSABLE (link
))
14417 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link
)) = 1;
14419 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link
)) = 0;
14423 /* If the level being exited is the top level of a function,
14424 check over all the labels, and clear out the current
14425 (function local) meanings of their names. */
14429 /* If this is the top level block of a function,
14430 the vars are the function's parameters.
14431 Don't leave them in the BLOCK because they are
14432 found in the FUNCTION_DECL instead. */
14434 BLOCK_VARS (block
) = 0;
14437 /* Pop the current level, and free the structure for reuse. */
14440 register struct f_binding_level
*level
= current_binding_level
;
14441 current_binding_level
= current_binding_level
->level_chain
;
14443 level
->level_chain
= free_binding_level
;
14444 free_binding_level
= level
;
14447 /* Dispose of the block that we just made inside some higher level. */
14449 && current_function_decl
!= error_mark_node
)
14450 DECL_INITIAL (current_function_decl
) = block
;
14453 if (!block_previously_created
)
14454 current_binding_level
->blocks
14455 = chainon (current_binding_level
->blocks
, block
);
14457 /* If we did not make a block for the level just exited,
14458 any blocks made for inner levels
14459 (since they cannot be recorded as subblocks in that level)
14460 must be carried forward so they will later become subblocks
14461 of something else. */
14462 else if (subblocks
)
14463 current_binding_level
->blocks
14464 = chainon (current_binding_level
->blocks
, subblocks
);
14467 TREE_USED (block
) = 1;
14472 ffe_print_identifier (FILE *file
, tree node
, int indent
)
14474 print_node (file
, "global", IDENTIFIER_GLOBAL_VALUE (node
), indent
+ 4);
14475 print_node (file
, "local", IDENTIFIER_LOCAL_VALUE (node
), indent
+ 4);
14478 /* Record a decl-node X as belonging to the current lexical scope.
14479 Check for errors (such as an incompatible declaration for the same
14480 name already seen in the same scope).
14482 Returns either X or an old decl for the same name.
14483 If an old decl is returned, it may have been smashed
14484 to agree with what X says. */
14490 register tree name
= DECL_NAME (x
);
14491 register struct f_binding_level
*b
= current_binding_level
;
14493 if ((TREE_CODE (x
) == FUNCTION_DECL
)
14494 && (DECL_INITIAL (x
) == 0)
14495 && DECL_EXTERNAL (x
))
14496 DECL_CONTEXT (x
) = NULL_TREE
;
14498 DECL_CONTEXT (x
) = current_function_decl
;
14502 if (IDENTIFIER_INVENTED (name
))
14504 DECL_ARTIFICIAL (x
) = 1;
14505 DECL_IN_SYSTEM_HEADER (x
) = 1;
14508 t
= lookup_name_current_level (name
);
14510 assert ((t
== NULL_TREE
) || (DECL_CONTEXT (x
) == NULL_TREE
));
14512 /* Don't push non-parms onto list for parms until we understand
14513 why we're doing this and whether it works. */
14515 assert ((b
== global_binding_level
)
14516 || !ffecom_transform_only_dummies_
14517 || TREE_CODE (x
) == PARM_DECL
);
14519 if ((t
!= NULL_TREE
) && duplicate_decls (x
, t
))
14522 /* If we are processing a typedef statement, generate a whole new
14523 ..._TYPE node (which will be just an variant of the existing
14524 ..._TYPE node with identical properties) and then install the
14525 TYPE_DECL node generated to represent the typedef name as the
14526 TYPE_NAME of this brand new (duplicate) ..._TYPE node.
14528 The whole point here is to end up with a situation where each and every
14529 ..._TYPE node the compiler creates will be uniquely associated with
14530 AT MOST one node representing a typedef name. This way, even though
14531 the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL
14532 (i.e. "typedef name") nodes very early on, later parts of the
14533 compiler can always do the reverse translation and get back the
14534 corresponding typedef name. For example, given:
14536 typedef struct S MY_TYPE; MY_TYPE object;
14538 Later parts of the compiler might only know that `object' was of type
14539 `struct S' if it were not for code just below. With this code
14540 however, later parts of the compiler see something like:
14542 struct S' == struct S typedef struct S' MY_TYPE; struct S' object;
14544 And they can then deduce (from the node for type struct S') that the
14545 original object declaration was:
14549 Being able to do this is important for proper support of protoize, and
14550 also for generating precise symbolic debugging information which
14551 takes full account of the programmer's (typedef) vocabulary.
14553 Obviously, we don't want to generate a duplicate ..._TYPE node if the
14554 TYPE_DECL node that we are now processing really represents a
14555 standard built-in type.
14557 Since all standard types are effectively declared at line zero in the
14558 source file, we can easily check to see if we are working on a
14559 standard type by checking the current value of lineno. */
14561 if (TREE_CODE (x
) == TYPE_DECL
)
14563 if (DECL_SOURCE_LINE (x
) == 0)
14565 if (TYPE_NAME (TREE_TYPE (x
)) == 0)
14566 TYPE_NAME (TREE_TYPE (x
)) = x
;
14568 else if (TREE_TYPE (x
) != error_mark_node
)
14570 tree tt
= TREE_TYPE (x
);
14572 tt
= build_type_copy (tt
);
14573 TYPE_NAME (tt
) = x
;
14574 TREE_TYPE (x
) = tt
;
14578 /* This name is new in its binding level. Install the new declaration
14580 if (b
== global_binding_level
)
14581 IDENTIFIER_GLOBAL_VALUE (name
) = x
;
14583 IDENTIFIER_LOCAL_VALUE (name
) = x
;
14586 /* Put decls on list in reverse order. We will reverse them later if
14588 TREE_CHAIN (x
) = b
->names
;
14594 /* Nonzero if the current level needs to have a BLOCK made. */
14601 for (decl
= current_binding_level
->names
;
14603 decl
= TREE_CHAIN (decl
))
14605 if (TREE_USED (decl
) || TREE_CODE (decl
) != VAR_DECL
14606 || (DECL_NAME (decl
) && ! DECL_ARTIFICIAL (decl
)))
14607 /* Currently, there aren't supposed to be non-artificial names
14608 at other than the top block for a function -- they're
14609 believed to always be temps. But it's wise to check anyway. */
14615 /* Enter a new binding level.
14616 If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
14617 not for that of tags. */
14620 pushlevel (int tag_transparent
)
14622 register struct f_binding_level
*newlevel
= NULL_BINDING_LEVEL
;
14624 assert (! tag_transparent
);
14626 if (current_binding_level
== global_binding_level
)
14631 /* Reuse or create a struct for this binding level. */
14633 if (free_binding_level
)
14635 newlevel
= free_binding_level
;
14636 free_binding_level
= free_binding_level
->level_chain
;
14640 newlevel
= make_binding_level ();
14643 /* Add this level to the front of the chain (stack) of levels that
14646 *newlevel
= clear_binding_level
;
14647 newlevel
->level_chain
= current_binding_level
;
14648 current_binding_level
= newlevel
;
14651 /* Set the BLOCK node for the innermost scope
14652 (the one we are currently in). */
14655 set_block (tree block
)
14657 current_binding_level
->this_block
= block
;
14658 current_binding_level
->names
= chainon (current_binding_level
->names
,
14659 BLOCK_VARS (block
));
14660 current_binding_level
->blocks
= chainon (current_binding_level
->blocks
,
14661 BLOCK_SUBBLOCKS (block
));
14665 ffe_signed_or_unsigned_type (int unsignedp
, tree type
)
14669 if (! INTEGRAL_TYPE_P (type
))
14671 if (TYPE_PRECISION (type
) == TYPE_PRECISION (signed_char_type_node
))
14672 return unsignedp
? unsigned_char_type_node
: signed_char_type_node
;
14673 if (TYPE_PRECISION (type
) == TYPE_PRECISION (integer_type_node
))
14674 return unsignedp
? unsigned_type_node
: integer_type_node
;
14675 if (TYPE_PRECISION (type
) == TYPE_PRECISION (short_integer_type_node
))
14676 return unsignedp
? short_unsigned_type_node
: short_integer_type_node
;
14677 if (TYPE_PRECISION (type
) == TYPE_PRECISION (long_integer_type_node
))
14678 return unsignedp
? long_unsigned_type_node
: long_integer_type_node
;
14679 if (TYPE_PRECISION (type
) == TYPE_PRECISION (long_long_integer_type_node
))
14680 return (unsignedp
? long_long_unsigned_type_node
14681 : long_long_integer_type_node
);
14683 type2
= ffe_type_for_size (TYPE_PRECISION (type
), unsignedp
);
14684 if (type2
== NULL_TREE
)
14691 ffe_signed_type (tree type
)
14693 tree type1
= TYPE_MAIN_VARIANT (type
);
14694 ffeinfoKindtype kt
;
14697 if (type1
== unsigned_char_type_node
|| type1
== char_type_node
)
14698 return signed_char_type_node
;
14699 if (type1
== unsigned_type_node
)
14700 return integer_type_node
;
14701 if (type1
== short_unsigned_type_node
)
14702 return short_integer_type_node
;
14703 if (type1
== long_unsigned_type_node
)
14704 return long_integer_type_node
;
14705 if (type1
== long_long_unsigned_type_node
)
14706 return long_long_integer_type_node
;
14707 #if 0 /* gcc/c-* files only */
14708 if (type1
== unsigned_intDI_type_node
)
14709 return intDI_type_node
;
14710 if (type1
== unsigned_intSI_type_node
)
14711 return intSI_type_node
;
14712 if (type1
== unsigned_intHI_type_node
)
14713 return intHI_type_node
;
14714 if (type1
== unsigned_intQI_type_node
)
14715 return intQI_type_node
;
14718 type2
= ffe_type_for_size (TYPE_PRECISION (type1
), 0);
14719 if (type2
!= NULL_TREE
)
14722 for (kt
= 0; kt
< ARRAY_SIZE (ffecom_tree_type
[0]); ++kt
)
14724 type2
= ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][kt
];
14726 if (type1
== type2
)
14727 return ffecom_tree_type
[FFEINFO_basictypeINTEGER
][kt
];
14733 /* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
14734 or validate its data type for an `if' or `while' statement or ?..: exp.
14736 This preparation consists of taking the ordinary
14737 representation of an expression expr and producing a valid tree
14738 boolean expression describing whether expr is nonzero. We could
14739 simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1),
14740 but we optimize comparisons, &&, ||, and !.
14742 The resulting type should always be `integer_type_node'. */
14745 ffe_truthvalue_conversion (tree expr
)
14747 if (TREE_CODE (expr
) == ERROR_MARK
)
14750 #if 0 /* This appears to be wrong for C++. */
14751 /* These really should return error_mark_node after 2.4 is stable.
14752 But not all callers handle ERROR_MARK properly. */
14753 switch (TREE_CODE (TREE_TYPE (expr
)))
14756 error ("struct type value used where scalar is required");
14757 return integer_zero_node
;
14760 error ("union type value used where scalar is required");
14761 return integer_zero_node
;
14764 error ("array type value used where scalar is required");
14765 return integer_zero_node
;
14772 switch (TREE_CODE (expr
))
14774 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14775 or comparison expressions as truth values at this level. */
14777 case COMPONENT_REF
:
14778 /* A one-bit unsigned bit-field is already acceptable. */
14779 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr
, 1)))
14780 && TREE_UNSIGNED (TREE_OPERAND (expr
, 1)))
14786 /* It is simpler and generates better code to have only TRUTH_*_EXPR
14787 or comparison expressions as truth values at this level. */
14789 if (integer_zerop (TREE_OPERAND (expr
, 1)))
14790 return build_unary_op (TRUTH_NOT_EXPR
, TREE_OPERAND (expr
, 0), 0);
14792 case NE_EXPR
: case LE_EXPR
: case GE_EXPR
: case LT_EXPR
: case GT_EXPR
:
14793 case TRUTH_ANDIF_EXPR
:
14794 case TRUTH_ORIF_EXPR
:
14795 case TRUTH_AND_EXPR
:
14796 case TRUTH_OR_EXPR
:
14797 case TRUTH_XOR_EXPR
:
14798 TREE_TYPE (expr
) = integer_type_node
;
14805 return integer_zerop (expr
) ? integer_zero_node
: integer_one_node
;
14808 return real_zerop (expr
) ? integer_zero_node
: integer_one_node
;
14811 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr
, 0)))
14812 return build (COMPOUND_EXPR
, integer_type_node
,
14813 TREE_OPERAND (expr
, 0), integer_one_node
);
14815 return integer_one_node
;
14818 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr
, 1))
14819 ? TRUTH_OR_EXPR
: TRUTH_ORIF_EXPR
),
14821 ffe_truthvalue_conversion (TREE_OPERAND (expr
, 0)),
14822 ffe_truthvalue_conversion (TREE_OPERAND (expr
, 1)));
14828 /* These don't change whether an object is nonzero or zero. */
14829 return ffe_truthvalue_conversion (TREE_OPERAND (expr
, 0));
14833 /* These don't change whether an object is zero or nonzero, but
14834 we can't ignore them if their second arg has side-effects. */
14835 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr
, 1)))
14836 return build (COMPOUND_EXPR
, integer_type_node
, TREE_OPERAND (expr
, 1),
14837 ffe_truthvalue_conversion (TREE_OPERAND (expr
, 0)));
14839 return ffe_truthvalue_conversion (TREE_OPERAND (expr
, 0));
14843 /* Distribute the conversion into the arms of a COND_EXPR. */
14844 tree arg1
= TREE_OPERAND (expr
, 1);
14845 tree arg2
= TREE_OPERAND (expr
, 2);
14846 if (! VOID_TYPE_P (TREE_TYPE (arg1
)))
14847 arg1
= ffe_truthvalue_conversion (arg1
);
14848 if (! VOID_TYPE_P (TREE_TYPE (arg2
)))
14849 arg2
= ffe_truthvalue_conversion (arg2
);
14850 return fold (build (COND_EXPR
, integer_type_node
,
14851 TREE_OPERAND (expr
, 0), arg1
, arg2
));
14855 /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
14856 since that affects how `default_conversion' will behave. */
14857 if (TREE_CODE (TREE_TYPE (expr
)) == REFERENCE_TYPE
14858 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr
, 0))) == REFERENCE_TYPE
)
14860 /* fall through... */
14862 /* If this is widening the argument, we can ignore it. */
14863 if (TYPE_PRECISION (TREE_TYPE (expr
))
14864 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr
, 0))))
14865 return ffe_truthvalue_conversion (TREE_OPERAND (expr
, 0));
14869 /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize
14871 if (TARGET_FLOAT_FORMAT
== IEEE_FLOAT_FORMAT
14872 && TREE_CODE (TREE_TYPE (expr
)) == REAL_TYPE
)
14874 /* fall through... */
14876 /* This and MINUS_EXPR can be changed into a comparison of the
14878 if (TREE_TYPE (TREE_OPERAND (expr
, 0))
14879 == TREE_TYPE (TREE_OPERAND (expr
, 1)))
14880 return ffecom_2 (NE_EXPR
, integer_type_node
,
14881 TREE_OPERAND (expr
, 0),
14882 TREE_OPERAND (expr
, 1));
14883 return ffecom_2 (NE_EXPR
, integer_type_node
,
14884 TREE_OPERAND (expr
, 0),
14885 fold (build1 (NOP_EXPR
,
14886 TREE_TYPE (TREE_OPERAND (expr
, 0)),
14887 TREE_OPERAND (expr
, 1))));
14890 if (integer_onep (TREE_OPERAND (expr
, 1)))
14895 #if 0 /* No such thing in Fortran. */
14896 if (warn_parentheses
&& C_EXP_ORIGINAL_CODE (expr
) == MODIFY_EXPR
)
14897 warning ("suggest parentheses around assignment used as truth value");
14905 if (TREE_CODE (TREE_TYPE (expr
)) == COMPLEX_TYPE
)
14907 ((TREE_SIDE_EFFECTS (expr
)
14908 ? TRUTH_OR_EXPR
: TRUTH_ORIF_EXPR
),
14910 ffe_truthvalue_conversion (ffecom_1 (REALPART_EXPR
,
14911 TREE_TYPE (TREE_TYPE (expr
)),
14913 ffe_truthvalue_conversion (ffecom_1 (IMAGPART_EXPR
,
14914 TREE_TYPE (TREE_TYPE (expr
)),
14917 return ffecom_2 (NE_EXPR
, integer_type_node
,
14919 convert (TREE_TYPE (expr
), integer_zero_node
));
14923 ffe_type_for_mode (enum machine_mode mode
, int unsignedp
)
14929 if (mode
== TYPE_MODE (integer_type_node
))
14930 return unsignedp
? unsigned_type_node
: integer_type_node
;
14932 if (mode
== TYPE_MODE (signed_char_type_node
))
14933 return unsignedp
? unsigned_char_type_node
: signed_char_type_node
;
14935 if (mode
== TYPE_MODE (short_integer_type_node
))
14936 return unsignedp
? short_unsigned_type_node
: short_integer_type_node
;
14938 if (mode
== TYPE_MODE (long_integer_type_node
))
14939 return unsignedp
? long_unsigned_type_node
: long_integer_type_node
;
14941 if (mode
== TYPE_MODE (long_long_integer_type_node
))
14942 return unsignedp
? long_long_unsigned_type_node
: long_long_integer_type_node
;
14944 #if HOST_BITS_PER_WIDE_INT >= 64
14945 if (mode
== TYPE_MODE (intTI_type_node
))
14946 return unsignedp
? unsigned_intTI_type_node
: intTI_type_node
;
14949 if (mode
== TYPE_MODE (float_type_node
))
14950 return float_type_node
;
14952 if (mode
== TYPE_MODE (double_type_node
))
14953 return double_type_node
;
14955 if (mode
== TYPE_MODE (long_double_type_node
))
14956 return long_double_type_node
;
14958 if (mode
== TYPE_MODE (build_pointer_type (char_type_node
)))
14959 return build_pointer_type (char_type_node
);
14961 if (mode
== TYPE_MODE (build_pointer_type (integer_type_node
)))
14962 return build_pointer_type (integer_type_node
);
14964 for (i
= 0; ((size_t) i
) < ARRAY_SIZE (ffecom_tree_type
); ++i
)
14965 for (j
= 0; ((size_t) j
) < ARRAY_SIZE (ffecom_tree_type
[0]); ++j
)
14967 if (((t
= ffecom_tree_type
[i
][j
]) != NULL_TREE
)
14968 && (mode
== TYPE_MODE (t
)))
14970 if ((i
== FFEINFO_basictypeINTEGER
) && unsignedp
)
14971 return ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][j
];
14981 ffe_type_for_size (unsigned bits
, int unsignedp
)
14983 ffeinfoKindtype kt
;
14986 if (bits
== TYPE_PRECISION (integer_type_node
))
14987 return unsignedp
? unsigned_type_node
: integer_type_node
;
14989 if (bits
== TYPE_PRECISION (signed_char_type_node
))
14990 return unsignedp
? unsigned_char_type_node
: signed_char_type_node
;
14992 if (bits
== TYPE_PRECISION (short_integer_type_node
))
14993 return unsignedp
? short_unsigned_type_node
: short_integer_type_node
;
14995 if (bits
== TYPE_PRECISION (long_integer_type_node
))
14996 return unsignedp
? long_unsigned_type_node
: long_integer_type_node
;
14998 if (bits
== TYPE_PRECISION (long_long_integer_type_node
))
14999 return (unsignedp
? long_long_unsigned_type_node
15000 : long_long_integer_type_node
);
15002 for (kt
= 0; kt
< ARRAY_SIZE (ffecom_tree_type
[0]); ++kt
)
15004 type_node
= ffecom_tree_type
[FFEINFO_basictypeINTEGER
][kt
];
15006 if ((type_node
!= NULL_TREE
) && (bits
== TYPE_PRECISION (type_node
)))
15007 return unsignedp
? ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][kt
]
15015 ffe_unsigned_type (tree type
)
15017 tree type1
= TYPE_MAIN_VARIANT (type
);
15018 ffeinfoKindtype kt
;
15021 if (type1
== signed_char_type_node
|| type1
== char_type_node
)
15022 return unsigned_char_type_node
;
15023 if (type1
== integer_type_node
)
15024 return unsigned_type_node
;
15025 if (type1
== short_integer_type_node
)
15026 return short_unsigned_type_node
;
15027 if (type1
== long_integer_type_node
)
15028 return long_unsigned_type_node
;
15029 if (type1
== long_long_integer_type_node
)
15030 return long_long_unsigned_type_node
;
15031 #if 0 /* gcc/c-* files only */
15032 if (type1
== intDI_type_node
)
15033 return unsigned_intDI_type_node
;
15034 if (type1
== intSI_type_node
)
15035 return unsigned_intSI_type_node
;
15036 if (type1
== intHI_type_node
)
15037 return unsigned_intHI_type_node
;
15038 if (type1
== intQI_type_node
)
15039 return unsigned_intQI_type_node
;
15042 type2
= ffe_type_for_size (TYPE_PRECISION (type1
), 1);
15043 if (type2
!= NULL_TREE
)
15046 for (kt
= 0; kt
< ARRAY_SIZE (ffecom_tree_type
[0]); ++kt
)
15048 type2
= ffecom_tree_type
[FFEINFO_basictypeINTEGER
][kt
];
15050 if (type1
== type2
)
15051 return ffecom_tree_type
[FFEINFO_basictypeHOLLERITH
][kt
];
15057 /* From gcc/cccp.c, the code to handle -I. */
15059 /* Skip leading "./" from a directory name.
15060 This may yield the empty string, which represents the current directory. */
15062 static const char *
15063 skip_redundant_dir_prefix (const char *dir
)
15065 while (dir
[0] == '.' && dir
[1] == '/')
15066 for (dir
+= 2; *dir
== '/'; dir
++)
15068 if (dir
[0] == '.' && !dir
[1])
15073 /* The file_name_map structure holds a mapping of file names for a
15074 particular directory. This mapping is read from the file named
15075 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
15076 map filenames on a file system with severe filename restrictions,
15077 such as DOS. The format of the file name map file is just a series
15078 of lines with two tokens on each line. The first token is the name
15079 to map, and the second token is the actual name to use. */
15081 struct file_name_map
15083 struct file_name_map
*map_next
;
15088 #define FILE_NAME_MAP_FILE "header.gcc"
15090 /* Current maximum length of directory names in the search path
15091 for include files. (Altered as we get more of them.) */
15093 static int max_include_len
= 0;
15095 struct file_name_list
15097 struct file_name_list
*next
;
15099 /* Mapping of file names for this directory. */
15100 struct file_name_map
*name_map
;
15101 /* Nonzero if name_map is valid. */
15105 static struct file_name_list
*include
= NULL
; /* First dir to search */
15106 static struct file_name_list
*last_include
= NULL
; /* Last in chain */
15108 /* I/O buffer structure.
15109 The `fname' field is nonzero for source files and #include files
15110 and for the dummy text used for -D and -U.
15111 It is zero for rescanning results of macro expansion
15112 and for expanding macro arguments. */
15113 #define INPUT_STACK_MAX 400
15114 static struct file_buf
{
15116 /* Filename specified with #line command. */
15117 const char *nominal_fname
;
15118 /* Record where in the search path this file was found.
15119 For #include_next. */
15120 struct file_name_list
*dir
;
15122 ffewhereColumn column
;
15123 } instack
[INPUT_STACK_MAX
];
15125 static int last_error_tick
= 0; /* Incremented each time we print it. */
15126 static int input_file_stack_tick
= 0; /* Incremented when status changes. */
15128 /* Current nesting level of input sources.
15129 `instack[indepth]' is the level currently being read. */
15130 static int indepth
= -1;
15132 typedef struct file_buf FILE_BUF
;
15134 /* Nonzero means -I- has been seen,
15135 so don't look for #include "foo" the source-file directory. */
15136 static int ignore_srcdir
;
15138 #ifndef INCLUDE_LEN_FUDGE
15139 #define INCLUDE_LEN_FUDGE 0
15142 static void append_include_chain (struct file_name_list
*first
,
15143 struct file_name_list
*last
);
15144 static FILE *open_include_file (char *filename
,
15145 struct file_name_list
*searchptr
);
15146 static void print_containing_files (ffebadSeverity sev
);
15147 static char *read_filename_string (int ch
, FILE *f
);
15148 static struct file_name_map
*read_name_map (const char *dirname
);
15150 /* Append a chain of `struct file_name_list's
15151 to the end of the main include chain.
15152 FIRST is the beginning of the chain to append, and LAST is the end. */
15155 append_include_chain (struct file_name_list
*first
, struct file_name_list
*last
)
15157 struct file_name_list
*dir
;
15159 if (!first
|| !last
)
15165 last_include
->next
= first
;
15167 for (dir
= first
; ; dir
= dir
->next
) {
15168 int len
= strlen (dir
->fname
) + INCLUDE_LEN_FUDGE
;
15169 if (len
> max_include_len
)
15170 max_include_len
= len
;
15176 last_include
= last
;
15179 /* Try to open include file FILENAME. SEARCHPTR is the directory
15180 being tried from the include file search path. This function maps
15181 filenames on file systems based on information read by
15185 open_include_file (char *filename
, struct file_name_list
*searchptr
)
15187 register struct file_name_map
*map
;
15188 register char *from
;
15191 if (searchptr
&& ! searchptr
->got_name_map
)
15193 searchptr
->name_map
= read_name_map (searchptr
->fname
15194 ? searchptr
->fname
: ".");
15195 searchptr
->got_name_map
= 1;
15198 /* First check the mapping for the directory we are using. */
15199 if (searchptr
&& searchptr
->name_map
)
15202 if (searchptr
->fname
)
15203 from
+= strlen (searchptr
->fname
) + 1;
15204 for (map
= searchptr
->name_map
; map
; map
= map
->map_next
)
15206 if (! strcmp (map
->map_from
, from
))
15208 /* Found a match. */
15209 return fopen (map
->map_to
, "r");
15214 /* Try to find a mapping file for the particular directory we are
15215 looking in. Thus #include <sys/types.h> will look up sys/types.h
15216 in /usr/include/header.gcc and look up types.h in
15217 /usr/include/sys/header.gcc. */
15218 p
= strrchr (filename
, '/');
15219 #ifdef DIR_SEPARATOR
15220 if (! p
) p
= strrchr (filename
, DIR_SEPARATOR
);
15222 char *tmp
= strrchr (filename
, DIR_SEPARATOR
);
15223 if (tmp
!= NULL
&& tmp
> p
) p
= tmp
;
15229 && searchptr
->fname
15230 && strlen (searchptr
->fname
) == (size_t) (p
- filename
)
15231 && ! strncmp (searchptr
->fname
, filename
, (int) (p
- filename
)))
15233 /* FILENAME is in SEARCHPTR, which we've already checked. */
15234 return fopen (filename
, "r");
15240 map
= read_name_map (".");
15244 dir
= (char *) xmalloc (p
- filename
+ 1);
15245 memcpy (dir
, filename
, p
- filename
);
15246 dir
[p
- filename
] = '\0';
15248 map
= read_name_map (dir
);
15251 for (; map
; map
= map
->map_next
)
15252 if (! strcmp (map
->map_from
, from
))
15253 return fopen (map
->map_to
, "r");
15255 return fopen (filename
, "r");
15258 /* Print the file names and line numbers of the #include
15259 commands which led to the current file. */
15262 print_containing_files (ffebadSeverity sev
)
15264 FILE_BUF
*ip
= NULL
;
15270 /* If stack of files hasn't changed since we last printed
15271 this info, don't repeat it. */
15272 if (last_error_tick
== input_file_stack_tick
)
15275 for (i
= indepth
; i
>= 0; i
--)
15276 if (instack
[i
].fname
!= NULL
) {
15281 /* Give up if we don't find a source file. */
15285 /* Find the other, outer source files. */
15286 for (i
--; i
>= 0; i
--)
15287 if (instack
[i
].fname
!= NULL
)
15293 str1
= "In file included";
15305 /* xgettext:no-c-format */
15306 ffebad_start_msg ("%A from %B at %0%C", sev
);
15307 ffebad_here (0, ip
->line
, ip
->column
);
15308 ffebad_string (str1
);
15309 ffebad_string (ip
->nominal_fname
);
15310 ffebad_string (str2
);
15314 /* Record we have printed the status as of this time. */
15315 last_error_tick
= input_file_stack_tick
;
15318 /* Read a space delimited string of unlimited length from a stdio
15322 read_filename_string (int ch
, FILE *f
)
15328 set
= alloc
= xmalloc (len
+ 1);
15329 if (! ISSPACE (ch
))
15332 while ((ch
= getc (f
)) != EOF
&& ! ISSPACE (ch
))
15334 if (set
- alloc
== len
)
15337 alloc
= xrealloc (alloc
, len
+ 1);
15338 set
= alloc
+ len
/ 2;
15348 /* Read the file name map file for DIRNAME. */
15350 static struct file_name_map
*
15351 read_name_map (const char *dirname
)
15353 /* This structure holds a linked list of file name maps, one per
15355 struct file_name_map_list
15357 struct file_name_map_list
*map_list_next
;
15358 char *map_list_name
;
15359 struct file_name_map
*map_list_map
;
15361 static struct file_name_map_list
*map_list
;
15362 register struct file_name_map_list
*map_list_ptr
;
15366 int separator_needed
;
15368 dirname
= skip_redundant_dir_prefix (dirname
);
15370 for (map_list_ptr
= map_list
; map_list_ptr
;
15371 map_list_ptr
= map_list_ptr
->map_list_next
)
15372 if (! strcmp (map_list_ptr
->map_list_name
, dirname
))
15373 return map_list_ptr
->map_list_map
;
15375 map_list_ptr
= ((struct file_name_map_list
*)
15376 xmalloc (sizeof (struct file_name_map_list
)));
15377 map_list_ptr
->map_list_name
= xstrdup (dirname
);
15378 map_list_ptr
->map_list_map
= NULL
;
15380 dirlen
= strlen (dirname
);
15381 separator_needed
= dirlen
!= 0 && dirname
[dirlen
- 1] != '/';
15382 if (separator_needed
)
15383 name
= concat (dirname
, "/", FILE_NAME_MAP_FILE
, NULL
);
15385 name
= concat (dirname
, FILE_NAME_MAP_FILE
, NULL
);
15386 f
= fopen (name
, "r");
15389 map_list_ptr
->map_list_map
= NULL
;
15394 while ((ch
= getc (f
)) != EOF
)
15397 struct file_name_map
*ptr
;
15401 from
= read_filename_string (ch
, f
);
15402 while ((ch
= getc (f
)) != EOF
&& ISSPACE (ch
) && ch
!= '\n')
15404 to
= read_filename_string (ch
, f
);
15406 ptr
= ((struct file_name_map
*)
15407 xmalloc (sizeof (struct file_name_map
)));
15408 ptr
->map_from
= from
;
15410 /* Make the real filename absolute. */
15415 if (separator_needed
)
15416 ptr
->map_to
= concat (dirname
, "/", to
, NULL
);
15418 ptr
->map_to
= concat (dirname
, to
, NULL
);
15422 ptr
->map_next
= map_list_ptr
->map_list_map
;
15423 map_list_ptr
->map_list_map
= ptr
;
15425 while ((ch
= getc (f
)) != '\n')
15432 map_list_ptr
->map_list_next
= map_list
;
15433 map_list
= map_list_ptr
;
15435 return map_list_ptr
->map_list_map
;
15439 ffecom_file_ (const char *name
)
15443 /* Do partial setup of input buffer for the sake of generating
15444 early #line directives (when -g is in effect). */
15446 fp
= &instack
[++indepth
];
15447 memset ((char *) fp
, 0, sizeof (FILE_BUF
));
15450 fp
->nominal_fname
= fp
->fname
= name
;
15454 ffecom_close_include_ (FILE *f
)
15459 input_file_stack_tick
++;
15461 ffewhere_line_kill (instack
[indepth
].line
);
15462 ffewhere_column_kill (instack
[indepth
].column
);
15466 ffecom_decode_include_option (const char *dir
)
15468 if (! ignore_srcdir
&& !strcmp (dir
, "-"))
15472 struct file_name_list
*dirtmp
= (struct file_name_list
*)
15473 xmalloc (sizeof (struct file_name_list
));
15474 dirtmp
->next
= 0; /* New one goes on the end */
15475 dirtmp
->fname
= dir
;
15476 dirtmp
->got_name_map
= 0;
15477 append_include_chain (dirtmp
, dirtmp
);
15481 /* Open INCLUDEd file. */
15484 ffecom_open_include_ (char *name
, ffewhereLine l
, ffewhereColumn c
)
15487 size_t flen
= strlen (fbeg
);
15488 struct file_name_list
*search_start
= include
; /* Chain of dirs to search */
15489 struct file_name_list dsp
[1]; /* First in chain, if #include "..." */
15490 struct file_name_list
*searchptr
= 0;
15491 char *fname
; /* Dynamically allocated fname buffer */
15498 dsp
[0].fname
= NULL
;
15500 /* If -I- was specified, don't search current dir, only spec'd ones. */
15501 if (!ignore_srcdir
)
15503 for (fp
= &instack
[indepth
]; fp
>= instack
; fp
--)
15509 if ((nam
= fp
->nominal_fname
) != NULL
)
15511 /* Found a named file. Figure out dir of the file,
15512 and put it in front of the search list. */
15513 dsp
[0].next
= search_start
;
15514 search_start
= dsp
;
15516 ep
= strrchr (nam
, '/');
15517 #ifdef DIR_SEPARATOR
15518 if (ep
== NULL
) ep
= strrchr (nam
, DIR_SEPARATOR
);
15520 char *tmp
= strrchr (nam
, DIR_SEPARATOR
);
15521 if (tmp
!= NULL
&& tmp
> ep
) ep
= tmp
;
15525 ep
= strrchr (nam
, ']');
15526 if (ep
== NULL
) ep
= strrchr (nam
, '>');
15527 if (ep
== NULL
) ep
= strrchr (nam
, ':');
15528 if (ep
!= NULL
) ep
++;
15533 fname
= xmalloc (n
+ 1);
15534 strncpy (fname
, nam
, n
);
15536 dsp
[0].fname
= fname
;
15537 if (n
+ INCLUDE_LEN_FUDGE
> max_include_len
)
15538 max_include_len
= n
+ INCLUDE_LEN_FUDGE
;
15541 dsp
[0].fname
= NULL
; /* Current directory */
15542 dsp
[0].got_name_map
= 0;
15548 /* Allocate this permanently, because it gets stored in the definitions
15550 fname
= xmalloc (max_include_len
+ flen
+ 4);
15551 /* + 2 above for slash and terminating null. */
15552 /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED
15555 /* If specified file name is absolute, just open it. */
15558 #ifdef DIR_SEPARATOR
15559 || *fbeg
== DIR_SEPARATOR
15563 strncpy (fname
, (char *) fbeg
, flen
);
15565 f
= open_include_file (fname
, NULL
);
15571 /* Search directory path, trying to open the file.
15572 Copy each filename tried into FNAME. */
15574 for (searchptr
= search_start
; searchptr
; searchptr
= searchptr
->next
)
15576 if (searchptr
->fname
)
15578 /* The empty string in a search path is ignored.
15579 This makes it possible to turn off entirely
15580 a standard piece of the list. */
15581 if (searchptr
->fname
[0] == 0)
15583 strcpy (fname
, skip_redundant_dir_prefix (searchptr
->fname
));
15584 if (fname
[0] && fname
[strlen (fname
) - 1] != '/')
15585 strcat (fname
, "/");
15586 fname
[strlen (fname
) + flen
] = 0;
15591 strncat (fname
, fbeg
, flen
);
15593 /* Change this 1/2 Unix 1/2 VMS file specification into a
15594 full VMS file specification */
15595 if (searchptr
->fname
&& (searchptr
->fname
[0] != 0))
15597 /* Fix up the filename */
15598 hack_vms_include_specification (fname
);
15602 /* This is a normal VMS filespec, so use it unchanged. */
15603 strncpy (fname
, (char *) fbeg
, flen
);
15605 #if 0 /* Not for g77. */
15606 /* if it's '#include filename', add the missing .h */
15607 if (strchr (fname
, '.') == NULL
)
15608 strcat (fname
, ".h");
15612 f
= open_include_file (fname
, searchptr
);
15614 if (f
== NULL
&& errno
== EACCES
)
15616 print_containing_files (FFEBAD_severityWARNING
);
15617 /* xgettext:no-c-format */
15618 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
15619 FFEBAD_severityWARNING
);
15620 ffebad_string (fname
);
15621 ffebad_here (0, l
, c
);
15632 /* A file that was not found. */
15634 strncpy (fname
, (char *) fbeg
, flen
);
15636 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE
));
15637 ffebad_start (FFEBAD_OPEN_INCLUDE
);
15638 ffebad_here (0, l
, c
);
15639 ffebad_string (fname
);
15643 if (dsp
[0].fname
!= NULL
)
15644 free ((char *) dsp
[0].fname
);
15649 if (indepth
>= (INPUT_STACK_MAX
- 1))
15651 print_containing_files (FFEBAD_severityFATAL
);
15652 /* xgettext:no-c-format */
15653 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
15654 FFEBAD_severityFATAL
);
15655 ffebad_string (fname
);
15656 ffebad_here (0, l
, c
);
15661 instack
[indepth
].line
= ffewhere_line_use (l
);
15662 instack
[indepth
].column
= ffewhere_column_use (c
);
15664 fp
= &instack
[indepth
+ 1];
15665 memset ((char *) fp
, 0, sizeof (FILE_BUF
));
15666 fp
->nominal_fname
= fp
->fname
= fname
;
15667 fp
->dir
= searchptr
;
15670 input_file_stack_tick
++;
15675 /**INDENT* (Do not reformat this comment even with -fca option.)
15676 Data-gathering files: Given the source file listed below, compiled with
15677 f2c I obtained the output file listed after that, and from the output
15678 file I derived the above code.
15680 -------- (begin input file to f2c)
15686 double precision D1,D2
15688 call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2)
15715 c FFEINTRIN_impACOS
15716 call fooR(ACOS(R1))
15717 c FFEINTRIN_impAIMAG
15718 call fooR(AIMAG(C1))
15719 c FFEINTRIN_impAINT
15720 call fooR(AINT(R1))
15721 c FFEINTRIN_impALOG
15722 call fooR(ALOG(R1))
15723 c FFEINTRIN_impALOG10
15724 call fooR(ALOG10(R1))
15725 c FFEINTRIN_impAMAX0
15726 call fooR(AMAX0(I1,I2))
15727 c FFEINTRIN_impAMAX1
15728 call fooR(AMAX1(R1,R2))
15729 c FFEINTRIN_impAMIN0
15730 call fooR(AMIN0(I1,I2))
15731 c FFEINTRIN_impAMIN1
15732 call fooR(AMIN1(R1,R2))
15733 c FFEINTRIN_impAMOD
15734 call fooR(AMOD(R1,R2))
15735 c FFEINTRIN_impANINT
15736 call fooR(ANINT(R1))
15737 c FFEINTRIN_impASIN
15738 call fooR(ASIN(R1))
15739 c FFEINTRIN_impATAN
15740 call fooR(ATAN(R1))
15741 c FFEINTRIN_impATAN2
15742 call fooR(ATAN2(R1,R2))
15743 c FFEINTRIN_impCABS
15744 call fooR(CABS(C1))
15745 c FFEINTRIN_impCCOS
15746 call fooC(CCOS(C1))
15747 c FFEINTRIN_impCEXP
15748 call fooC(CEXP(C1))
15749 c FFEINTRIN_impCHAR
15750 call fooA(CHAR(I1))
15751 c FFEINTRIN_impCLOG
15752 call fooC(CLOG(C1))
15753 c FFEINTRIN_impCONJG
15754 call fooC(CONJG(C1))
15757 c FFEINTRIN_impCOSH
15758 call fooR(COSH(R1))
15759 c FFEINTRIN_impCSIN
15760 call fooC(CSIN(C1))
15761 c FFEINTRIN_impCSQRT
15762 call fooC(CSQRT(C1))
15763 c FFEINTRIN_impDABS
15764 call fooD(DABS(D1))
15765 c FFEINTRIN_impDACOS
15766 call fooD(DACOS(D1))
15767 c FFEINTRIN_impDASIN
15768 call fooD(DASIN(D1))
15769 c FFEINTRIN_impDATAN
15770 call fooD(DATAN(D1))
15771 c FFEINTRIN_impDATAN2
15772 call fooD(DATAN2(D1,D2))
15773 c FFEINTRIN_impDCOS
15774 call fooD(DCOS(D1))
15775 c FFEINTRIN_impDCOSH
15776 call fooD(DCOSH(D1))
15777 c FFEINTRIN_impDDIM
15778 call fooD(DDIM(D1,D2))
15779 c FFEINTRIN_impDEXP
15780 call fooD(DEXP(D1))
15782 call fooR(DIM(R1,R2))
15783 c FFEINTRIN_impDINT
15784 call fooD(DINT(D1))
15785 c FFEINTRIN_impDLOG
15786 call fooD(DLOG(D1))
15787 c FFEINTRIN_impDLOG10
15788 call fooD(DLOG10(D1))
15789 c FFEINTRIN_impDMAX1
15790 call fooD(DMAX1(D1,D2))
15791 c FFEINTRIN_impDMIN1
15792 call fooD(DMIN1(D1,D2))
15793 c FFEINTRIN_impDMOD
15794 call fooD(DMOD(D1,D2))
15795 c FFEINTRIN_impDNINT
15796 call fooD(DNINT(D1))
15797 c FFEINTRIN_impDPROD
15798 call fooD(DPROD(R1,R2))
15799 c FFEINTRIN_impDSIGN
15800 call fooD(DSIGN(D1,D2))
15801 c FFEINTRIN_impDSIN
15802 call fooD(DSIN(D1))
15803 c FFEINTRIN_impDSINH
15804 call fooD(DSINH(D1))
15805 c FFEINTRIN_impDSQRT
15806 call fooD(DSQRT(D1))
15807 c FFEINTRIN_impDTAN
15808 call fooD(DTAN(D1))
15809 c FFEINTRIN_impDTANH
15810 call fooD(DTANH(D1))
15813 c FFEINTRIN_impIABS
15814 call fooI(IABS(I1))
15815 c FFEINTRIN_impICHAR
15816 call fooI(ICHAR(A1))
15817 c FFEINTRIN_impIDIM
15818 call fooI(IDIM(I1,I2))
15819 c FFEINTRIN_impIDNINT
15820 call fooI(IDNINT(D1))
15821 c FFEINTRIN_impINDEX
15822 call fooI(INDEX(A1,A2))
15823 c FFEINTRIN_impISIGN
15824 call fooI(ISIGN(I1,I2))
15828 call fooL(LGE(A1,A2))
15830 call fooL(LGT(A1,A2))
15832 call fooL(LLE(A1,A2))
15834 call fooL(LLT(A1,A2))
15835 c FFEINTRIN_impMAX0
15836 call fooI(MAX0(I1,I2))
15837 c FFEINTRIN_impMAX1
15838 call fooI(MAX1(R1,R2))
15839 c FFEINTRIN_impMIN0
15840 call fooI(MIN0(I1,I2))
15841 c FFEINTRIN_impMIN1
15842 call fooI(MIN1(R1,R2))
15844 call fooI(MOD(I1,I2))
15845 c FFEINTRIN_impNINT
15846 call fooI(NINT(R1))
15847 c FFEINTRIN_impSIGN
15848 call fooR(SIGN(R1,R2))
15851 c FFEINTRIN_impSINH
15852 call fooR(SINH(R1))
15853 c FFEINTRIN_impSQRT
15854 call fooR(SQRT(R1))
15857 c FFEINTRIN_impTANH
15858 call fooR(TANH(R1))
15859 c FFEINTRIN_imp_CMPLX_C
15860 call fooC(cmplx(C1,C2))
15861 c FFEINTRIN_imp_CMPLX_D
15862 call fooZ(cmplx(D1,D2))
15863 c FFEINTRIN_imp_CMPLX_I
15864 call fooC(cmplx(I1,I2))
15865 c FFEINTRIN_imp_CMPLX_R
15866 call fooC(cmplx(R1,R2))
15867 c FFEINTRIN_imp_DBLE_C
15868 call fooD(dble(C1))
15869 c FFEINTRIN_imp_DBLE_D
15870 call fooD(dble(D1))
15871 c FFEINTRIN_imp_DBLE_I
15872 call fooD(dble(I1))
15873 c FFEINTRIN_imp_DBLE_R
15874 call fooD(dble(R1))
15875 c FFEINTRIN_imp_INT_C
15877 c FFEINTRIN_imp_INT_D
15879 c FFEINTRIN_imp_INT_I
15881 c FFEINTRIN_imp_INT_R
15883 c FFEINTRIN_imp_REAL_C
15884 call fooR(real(C1))
15885 c FFEINTRIN_imp_REAL_D
15886 call fooR(real(D1))
15887 c FFEINTRIN_imp_REAL_I
15888 call fooR(real(I1))
15889 c FFEINTRIN_imp_REAL_R
15890 call fooR(real(R1))
15892 c FFEINTRIN_imp_INT_D:
15894 c FFEINTRIN_specIDINT
15895 call fooI(IDINT(D1))
15897 c FFEINTRIN_imp_INT_R:
15899 c FFEINTRIN_specIFIX
15900 call fooI(IFIX(R1))
15901 c FFEINTRIN_specINT
15904 c FFEINTRIN_imp_REAL_D:
15906 c FFEINTRIN_specSNGL
15907 call fooR(SNGL(D1))
15909 c FFEINTRIN_imp_REAL_I:
15911 c FFEINTRIN_specFLOAT
15912 call fooR(FLOAT(I1))
15913 c FFEINTRIN_specREAL
15914 call fooR(REAL(I1))
15917 -------- (end input file to f2c)
15919 -------- (begin output from providing above input file as input to:
15920 -------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \
15921 -------- -e "s:^#.*$::g"')
15923 // -- translated by f2c (version 19950223).
15924 You must link the resulting object file with the libraries:
15925 -lf2c -lm (in that order)
15929 // f2c.h -- Standard Fortran to C header file //
15931 /// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
15933 - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) //
15938 // F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems //
15939 // we assume short, float are OK //
15940 typedef long int // long int // integer;
15941 typedef char *address;
15942 typedef short int shortint;
15943 typedef float real;
15944 typedef double doublereal;
15945 typedef struct { real r, i; } complex;
15946 typedef struct { doublereal r, i; } doublecomplex;
15947 typedef long int // long int // logical;
15948 typedef short int shortlogical;
15949 typedef char logical1;
15950 typedef char integer1;
15951 // typedef long long longint; // // system-dependent //
15956 // Extern is for use with -E //
15970 typedef long int // int or long int // flag;
15971 typedef long int // int or long int // ftnlen;
15972 typedef long int // int or long int // ftnint;
15975 //external read, write//
15984 //internal read, write//
16014 //rewind, backspace, endfile//
16026 ftnint *inex; //parameters in standard's order//
16052 union Multitype { // for multiple entry points //
16063 typedef union Multitype Multitype;
16065 typedef long Long; // No longer used; formerly in Namelist //
16067 struct Vardesc { // for Namelist //
16073 typedef struct Vardesc Vardesc;
16080 typedef struct Namelist Namelist;
16089 // procedure parameter types for -A and -C++ //
16094 typedef int // Unknown procedure type // (*U_fp)();
16095 typedef shortint (*J_fp)();
16096 typedef integer (*I_fp)();
16097 typedef real (*R_fp)();
16098 typedef doublereal (*D_fp)(), (*E_fp)();
16099 typedef // Complex // void (*C_fp)();
16100 typedef // Double Complex // void (*Z_fp)();
16101 typedef logical (*L_fp)();
16102 typedef shortlogical (*K_fp)();
16103 typedef // Character // void (*H_fp)();
16104 typedef // Subroutine // int (*S_fp)();
16106 // E_fp is for real functions when -R is not specified //
16107 typedef void C_f; // complex function //
16108 typedef void H_f; // character function //
16109 typedef void Z_f; // double complex function //
16110 typedef doublereal E_f; // real function with -R not specified //
16112 // undef any lower-case symbols that your C compiler predefines, e.g.: //
16115 // (No such symbols should be defined in a strict ANSI C compiler.
16116 We can avoid trouble with f2c-translated code by using
16141 // Main program // MAIN__()
16143 // System generated locals //
16146 doublereal d__1, d__2;
16148 doublecomplex z__1, z__2, z__3;
16152 // Builtin functions //
16155 double pow_ri(), pow_di();
16159 double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(),
16160 asin(), atan(), atan2(), c_abs();
16161 void c_cos(), c_exp(), c_log(), r_cnjg();
16162 double cos(), cosh();
16163 void c_sin(), c_sqrt();
16164 double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(),
16165 d_sign(), sin(), sinh(), sqrt(), tan(), tanh();
16166 integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len();
16167 logical l_ge(), l_gt(), l_le(), l_lt();
16171 // Local variables //
16172 extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(),
16173 fool_(), fooz_(), getem_();
16174 static char a1[10], a2[10];
16175 static complex c1, c2;
16176 static doublereal d1, d2;
16177 static integer i1, i2;
16178 static real r1, r2;
16181 getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L);
16189 d__1 = (doublereal) i1;
16190 q__1.r = c1.r / d__1, q__1.i = c1.i / d__1;
16200 c_div(&q__1, &c1, &c2);
16202 q__1.r = c1.r / r1, q__1.i = c1.i / r1;
16204 z__1.r = c1.r / d1, z__1.i = c1.i / d1;
16207 i__1 = pow_ii(&i1, &i2);
16209 r__1 = pow_ri(&r1, &i1);
16211 d__1 = pow_di(&d1, &i1);
16213 pow_ci(&q__1, &c1, &i1);
16215 d__1 = (doublereal) r1;
16216 d__2 = (doublereal) r2;
16217 r__1 = pow_dd(&d__1, &d__2);
16219 d__2 = (doublereal) r1;
16220 d__1 = pow_dd(&d__2, &d1);
16222 d__1 = pow_dd(&d1, &d2);
16224 d__2 = (doublereal) r1;
16225 d__1 = pow_dd(&d1, &d__2);
16227 z__2.r = c1.r, z__2.i = c1.i;
16228 z__3.r = c2.r, z__3.i = c2.i;
16229 pow_zz(&z__1, &z__2, &z__3);
16230 q__1.r = z__1.r, q__1.i = z__1.i;
16232 z__2.r = c1.r, z__2.i = c1.i;
16233 z__3.r = r1, z__3.i = 0.;
16234 pow_zz(&z__1, &z__2, &z__3);
16235 q__1.r = z__1.r, q__1.i = z__1.i;
16237 z__2.r = c1.r, z__2.i = c1.i;
16238 z__3.r = d1, z__3.i = 0.;
16239 pow_zz(&z__1, &z__2, &z__3);
16241 // FFEINTRIN_impABS //
16242 r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ;
16244 // FFEINTRIN_impACOS //
16247 // FFEINTRIN_impAIMAG //
16248 r__1 = r_imag(&c1);
16250 // FFEINTRIN_impAINT //
16253 // FFEINTRIN_impALOG //
16256 // FFEINTRIN_impALOG10 //
16257 r__1 = r_lg10(&r1);
16259 // FFEINTRIN_impAMAX0 //
16260 r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16262 // FFEINTRIN_impAMAX1 //
16263 r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16265 // FFEINTRIN_impAMIN0 //
16266 r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16268 // FFEINTRIN_impAMIN1 //
16269 r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16271 // FFEINTRIN_impAMOD //
16272 r__1 = r_mod(&r1, &r2);
16274 // FFEINTRIN_impANINT //
16275 r__1 = r_nint(&r1);
16277 // FFEINTRIN_impASIN //
16280 // FFEINTRIN_impATAN //
16283 // FFEINTRIN_impATAN2 //
16284 r__1 = atan2(r1, r2);
16286 // FFEINTRIN_impCABS //
16289 // FFEINTRIN_impCCOS //
16292 // FFEINTRIN_impCEXP //
16295 // FFEINTRIN_impCHAR //
16296 *(unsigned char *)&ch__1[0] = i1;
16298 // FFEINTRIN_impCLOG //
16301 // FFEINTRIN_impCONJG //
16302 r_cnjg(&q__1, &c1);
16304 // FFEINTRIN_impCOS //
16307 // FFEINTRIN_impCOSH //
16310 // FFEINTRIN_impCSIN //
16313 // FFEINTRIN_impCSQRT //
16314 c_sqrt(&q__1, &c1);
16316 // FFEINTRIN_impDABS //
16317 d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ;
16319 // FFEINTRIN_impDACOS //
16322 // FFEINTRIN_impDASIN //
16325 // FFEINTRIN_impDATAN //
16328 // FFEINTRIN_impDATAN2 //
16329 d__1 = atan2(d1, d2);
16331 // FFEINTRIN_impDCOS //
16334 // FFEINTRIN_impDCOSH //
16337 // FFEINTRIN_impDDIM //
16338 d__1 = d_dim(&d1, &d2);
16340 // FFEINTRIN_impDEXP //
16343 // FFEINTRIN_impDIM //
16344 r__1 = r_dim(&r1, &r2);
16346 // FFEINTRIN_impDINT //
16349 // FFEINTRIN_impDLOG //
16352 // FFEINTRIN_impDLOG10 //
16353 d__1 = d_lg10(&d1);
16355 // FFEINTRIN_impDMAX1 //
16356 d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ;
16358 // FFEINTRIN_impDMIN1 //
16359 d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ;
16361 // FFEINTRIN_impDMOD //
16362 d__1 = d_mod(&d1, &d2);
16364 // FFEINTRIN_impDNINT //
16365 d__1 = d_nint(&d1);
16367 // FFEINTRIN_impDPROD //
16368 d__1 = (doublereal) r1 * r2;
16370 // FFEINTRIN_impDSIGN //
16371 d__1 = d_sign(&d1, &d2);
16373 // FFEINTRIN_impDSIN //
16376 // FFEINTRIN_impDSINH //
16379 // FFEINTRIN_impDSQRT //
16382 // FFEINTRIN_impDTAN //
16385 // FFEINTRIN_impDTANH //
16388 // FFEINTRIN_impEXP //
16391 // FFEINTRIN_impIABS //
16392 i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ;
16394 // FFEINTRIN_impICHAR //
16395 i__1 = *(unsigned char *)a1;
16397 // FFEINTRIN_impIDIM //
16398 i__1 = i_dim(&i1, &i2);
16400 // FFEINTRIN_impIDNINT //
16401 i__1 = i_dnnt(&d1);
16403 // FFEINTRIN_impINDEX //
16404 i__1 = i_indx(a1, a2, 10L, 10L);
16406 // FFEINTRIN_impISIGN //
16407 i__1 = i_sign(&i1, &i2);
16409 // FFEINTRIN_impLEN //
16410 i__1 = i_len(a1, 10L);
16412 // FFEINTRIN_impLGE //
16413 L__1 = l_ge(a1, a2, 10L, 10L);
16415 // FFEINTRIN_impLGT //
16416 L__1 = l_gt(a1, a2, 10L, 10L);
16418 // FFEINTRIN_impLLE //
16419 L__1 = l_le(a1, a2, 10L, 10L);
16421 // FFEINTRIN_impLLT //
16422 L__1 = l_lt(a1, a2, 10L, 10L);
16424 // FFEINTRIN_impMAX0 //
16425 i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ;
16427 // FFEINTRIN_impMAX1 //
16428 i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ;
16430 // FFEINTRIN_impMIN0 //
16431 i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ;
16433 // FFEINTRIN_impMIN1 //
16434 i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ;
16436 // FFEINTRIN_impMOD //
16439 // FFEINTRIN_impNINT //
16440 i__1 = i_nint(&r1);
16442 // FFEINTRIN_impSIGN //
16443 r__1 = r_sign(&r1, &r2);
16445 // FFEINTRIN_impSIN //
16448 // FFEINTRIN_impSINH //
16451 // FFEINTRIN_impSQRT //
16454 // FFEINTRIN_impTAN //
16457 // FFEINTRIN_impTANH //
16460 // FFEINTRIN_imp_CMPLX_C //
16463 q__1.r = r__1, q__1.i = r__2;
16465 // FFEINTRIN_imp_CMPLX_D //
16466 z__1.r = d1, z__1.i = d2;
16468 // FFEINTRIN_imp_CMPLX_I //
16471 q__1.r = r__1, q__1.i = r__2;
16473 // FFEINTRIN_imp_CMPLX_R //
16474 q__1.r = r1, q__1.i = r2;
16476 // FFEINTRIN_imp_DBLE_C //
16477 d__1 = (doublereal) c1.r;
16479 // FFEINTRIN_imp_DBLE_D //
16482 // FFEINTRIN_imp_DBLE_I //
16483 d__1 = (doublereal) i1;
16485 // FFEINTRIN_imp_DBLE_R //
16486 d__1 = (doublereal) r1;
16488 // FFEINTRIN_imp_INT_C //
16489 i__1 = (integer) c1.r;
16491 // FFEINTRIN_imp_INT_D //
16492 i__1 = (integer) d1;
16494 // FFEINTRIN_imp_INT_I //
16497 // FFEINTRIN_imp_INT_R //
16498 i__1 = (integer) r1;
16500 // FFEINTRIN_imp_REAL_C //
16503 // FFEINTRIN_imp_REAL_D //
16506 // FFEINTRIN_imp_REAL_I //
16509 // FFEINTRIN_imp_REAL_R //
16513 // FFEINTRIN_imp_INT_D: //
16515 // FFEINTRIN_specIDINT //
16516 i__1 = (integer) d1;
16519 // FFEINTRIN_imp_INT_R: //
16521 // FFEINTRIN_specIFIX //
16522 i__1 = (integer) r1;
16524 // FFEINTRIN_specINT //
16525 i__1 = (integer) r1;
16528 // FFEINTRIN_imp_REAL_D: //
16530 // FFEINTRIN_specSNGL //
16534 // FFEINTRIN_imp_REAL_I: //
16536 // FFEINTRIN_specFLOAT //
16539 // FFEINTRIN_specREAL //
16545 -------- (end output file from f2c)
16549 #include "gt-f-com.h"
16550 #include "gtype-f.h"