00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 #include "proj.h"
00084 #include "flags.h"
00085 #include "rtl.h"
00086 #include "toplev.h"
00087 #include "tree.h"
00088 #include "output.h"
00089 #include "convert.h"
00090 #include "ggc.h"
00091 #include "diagnostic.h"
00092 #include "intl.h"
00093 #include "langhooks.h"
00094 #include "langhooks-def.h"
00095
00096
00097 #ifdef VMS
00098 #include <descrip.h>
00099 #define O_RDONLY 0
00100 #define O_WRONLY 1
00101 #define read(fd,buf,size) VMS_read (fd,buf,size)
00102 #define write(fd,buf,size) VMS_write (fd,buf,size)
00103 #define open(fname,mode,prot) VMS_open (fname,mode,prot)
00104 #define fopen(fname,mode) VMS_fopen (fname,mode)
00105 #define freopen(fname,mode,ofile) VMS_freopen (fname,mode,ofile)
00106 #define strncat(dst,src,cnt) VMS_strncat (dst,src,cnt)
00107 #define fstat(fd,stbuf) VMS_fstat (fd,stbuf)
00108 static int VMS_fstat (), VMS_stat ();
00109 static char * VMS_strncat ();
00110 static int VMS_read ();
00111 static int VMS_write ();
00112 static int VMS_open ();
00113 static FILE * VMS_fopen ();
00114 static FILE * VMS_freopen ();
00115 static void hack_vms_include_specification ();
00116 typedef struct { unsigned :16, :16, :16; } vms_ino_t;
00117 #define ino_t vms_ino_t
00118 #define INCLUDE_LEN_FUDGE 10
00119 #endif
00120
00121 #define FFECOM_DETERMINE_TYPES 1
00122 #include "com.h"
00123 #include "bad.h"
00124 #include "bld.h"
00125 #include "equiv.h"
00126 #include "expr.h"
00127 #include "implic.h"
00128 #include "info.h"
00129 #include "malloc.h"
00130 #include "src.h"
00131 #include "st.h"
00132 #include "storag.h"
00133 #include "symbol.h"
00134 #include "target.h"
00135 #include "top.h"
00136 #include "type.h"
00137
00138
00139
00140
00141 FILE *finput;
00142
00143
00144
00145
00146
00147
00148
00149
00150 tree string_type_node;
00151
00152
00153
00154
00155
00156
00157 static tree ffecom_tree_fun_type_void;
00158
00159 tree ffecom_integer_type_node;
00160 tree ffecom_integer_zero_node;
00161 tree ffecom_integer_one_node;
00162 tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
00163
00164
00165
00166
00167
00168 static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
00169 static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
00170 static tree ffecom_tree_subr_type;
00171 static tree ffecom_tree_ptr_to_subr_type;
00172 static tree ffecom_tree_blockdata_type;
00173
00174 static tree ffecom_tree_xargc_;
00175
00176 ffecomSymbol ffecom_symbol_null_
00177 =
00178 {
00179 NULL_TREE,
00180 NULL_TREE,
00181 NULL_TREE,
00182 NULL_TREE,
00183 false
00184 };
00185 ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE;
00186 ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
00187
00188 int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
00189 tree ffecom_f2c_integer_type_node;
00190 tree ffecom_f2c_ptr_to_integer_type_node;
00191 tree ffecom_f2c_address_type_node;
00192 tree ffecom_f2c_real_type_node;
00193 tree ffecom_f2c_ptr_to_real_type_node;
00194 tree ffecom_f2c_doublereal_type_node;
00195 tree ffecom_f2c_complex_type_node;
00196 tree ffecom_f2c_doublecomplex_type_node;
00197 tree ffecom_f2c_longint_type_node;
00198 tree ffecom_f2c_logical_type_node;
00199 tree ffecom_f2c_flag_type_node;
00200 tree ffecom_f2c_ftnlen_type_node;
00201 tree ffecom_f2c_ftnlen_zero_node;
00202 tree ffecom_f2c_ftnlen_one_node;
00203 tree ffecom_f2c_ftnlen_two_node;
00204 tree ffecom_f2c_ptr_to_ftnlen_type_node;
00205 tree ffecom_f2c_ftnint_type_node;
00206 tree ffecom_f2c_ptr_to_ftnint_type_node;
00207
00208
00209
00210 #ifndef FFECOM_sizeMAXSTACKITEM
00211 #define FFECOM_sizeMAXSTACKITEM 32*1024
00212
00213
00214 #endif
00215
00216
00217
00218
00219
00220 #if FFECOM_sizeMAXSTACKITEM == 0
00221 #undef FFECOM_sizeMAXSTACKITEM
00222 #endif
00223
00224 typedef enum
00225 {
00226 FFECOM_rttypeVOID_,
00227 FFECOM_rttypeVOIDSTAR_,
00228 FFECOM_rttypeFTNINT_,
00229 FFECOM_rttypeINTEGER_,
00230 FFECOM_rttypeLONGINT_,
00231 FFECOM_rttypeLOGICAL_,
00232 FFECOM_rttypeREAL_F2C_,
00233 FFECOM_rttypeREAL_GNU_,
00234 FFECOM_rttypeCOMPLEX_F2C_,
00235 FFECOM_rttypeCOMPLEX_GNU_,
00236 FFECOM_rttypeDOUBLE_,
00237 FFECOM_rttypeDOUBLEREAL_,
00238 FFECOM_rttypeDBLCMPLX_F2C_,
00239 FFECOM_rttypeDBLCMPLX_GNU_,
00240 FFECOM_rttypeCHARACTER_,
00241 FFECOM_rttype_
00242 } ffecomRttype_;
00243
00244
00245
00246 typedef struct _ffecom_concat_list_ ffecomConcatList_;
00247
00248
00249
00250
00251
00252
00253 struct _ffecom_concat_list_
00254 {
00255 ffebld *exprs;
00256 int count;
00257 int max;
00258 ffetargetCharacterSize minlen;
00259 ffetargetCharacterSize maxlen;
00260 };
00261
00262
00263
00264 static void ffecom_init_decl_processing PARAMS ((void));
00265 static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
00266 static tree ffecom_widest_expr_type_ (ffebld list);
00267 static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
00268 tree dest_size, tree source_tree,
00269 ffebld source, bool scalar_arg);
00270 static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest,
00271 tree args, tree callee_commons,
00272 bool scalar_args);
00273 static tree ffecom_build_f2c_string_ (int i, const char *s);
00274 static tree ffecom_call_ (tree fn, ffeinfoKindtype kt,
00275 bool is_f2c_complex, tree type,
00276 tree args, tree dest_tree,
00277 ffebld dest, bool *dest_used,
00278 tree callee_commons, bool scalar_args, tree hook);
00279 static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt,
00280 bool is_f2c_complex, tree type,
00281 ffebld left, ffebld right,
00282 tree dest_tree, ffebld dest,
00283 bool *dest_used, tree callee_commons,
00284 bool scalar_args, bool ref, tree hook);
00285 static void ffecom_char_args_x_ (tree *xitem, tree *length,
00286 ffebld expr, bool with_null);
00287 static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy);
00288 static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s);
00289 static ffecomConcatList_
00290 ffecom_concat_list_gather_ (ffecomConcatList_ catlist,
00291 ffebld expr,
00292 ffetargetCharacterSize max);
00293 static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist);
00294 static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr,
00295 ffetargetCharacterSize max);
00296 static void ffecom_debug_kludge_ (tree aggr, const char *aggr_type,
00297 ffesymbol member, tree member_type,
00298 ffetargetOffset offset);
00299 static void ffecom_do_entry_ (ffesymbol fn, int entrynum);
00300 static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
00301 bool *dest_used, bool assignp, bool widenp);
00302 static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
00303 ffebld dest, bool *dest_used);
00304 static tree ffecom_expr_power_integer_ (ffebld expr);
00305 static void ffecom_expr_transform_ (ffebld expr);
00306 static void ffecom_f2c_make_type_ (tree *type, int tcode, const char *name);
00307 static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
00308 int code);
00309 static ffeglobal ffecom_finish_global_ (ffeglobal global);
00310 static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s);
00311 static tree ffecom_get_appended_identifier_ (char us, const char *text);
00312 static tree ffecom_get_external_identifier_ (ffesymbol s);
00313 static tree ffecom_get_identifier_ (const char *text);
00314 static tree ffecom_gen_sfuncdef_ (ffesymbol s,
00315 ffeinfoBasictype bt,
00316 ffeinfoKindtype kt);
00317 static const char *ffecom_gfrt_args_ (ffecomGfrt ix);
00318 static tree ffecom_gfrt_tree_ (ffecomGfrt ix);
00319 static tree ffecom_init_zero_ (tree decl);
00320 static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
00321 tree *maybe_tree);
00322 static tree ffecom_intrinsic_len_ (ffebld expr);
00323 static void ffecom_let_char_ (tree dest_tree,
00324 tree dest_length,
00325 ffetargetCharacterSize dest_size,
00326 ffebld source);
00327 static void ffecom_make_gfrt_ (ffecomGfrt ix);
00328 static void ffecom_member_phase1_ (ffestorag mst, ffestorag st);
00329 static void ffecom_member_phase2_ (ffestorag mst, ffestorag st);
00330 static void ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size,
00331 ffebld source);
00332 static void ffecom_push_dummy_decls_ (ffebld dumlist,
00333 bool stmtfunc);
00334 static void ffecom_start_progunit_ (void);
00335 static ffesymbol ffecom_sym_transform_ (ffesymbol s);
00336 static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s);
00337 static void ffecom_transform_common_ (ffesymbol s);
00338 static void ffecom_transform_equiv_ (ffestorag st);
00339 static tree ffecom_transform_namelist_ (ffesymbol s);
00340 static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
00341 tree t);
00342 static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
00343 tree *size, tree tree);
00344 static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right,
00345 tree dest_tree, ffebld dest,
00346 bool *dest_used, tree hook);
00347 static tree ffecom_type_localvar_ (ffesymbol s,
00348 ffeinfoBasictype bt,
00349 ffeinfoKindtype kt);
00350 static tree ffecom_type_namelist_ (void);
00351 static tree ffecom_type_vardesc_ (void);
00352 static tree ffecom_vardesc_ (ffebld expr);
00353 static tree ffecom_vardesc_array_ (ffesymbol s);
00354 static tree ffecom_vardesc_dims_ (ffesymbol s);
00355 static tree ffecom_convert_narrow_ (tree type, tree expr);
00356 static tree ffecom_convert_widen_ (tree type, tree expr);
00357
00358
00359
00360
00361 static tree bison_rule_compstmt_ (void);
00362 static void bison_rule_pushlevel_ (void);
00363 static void delete_block (tree block);
00364 static int duplicate_decls (tree newdecl, tree olddecl);
00365 static void finish_decl (tree decl, tree init, bool is_top_level);
00366 static void finish_function (int nested);
00367 static const char *lang_printable_name (tree decl, int v);
00368 static tree lookup_name_current_level (tree name);
00369 static struct binding_level *make_binding_level (void);
00370 static void pop_f_function_context (void);
00371 static void push_f_function_context (void);
00372 static void push_parm_decl (tree parm);
00373 static tree pushdecl_top_level (tree decl);
00374 static int kept_level_p (void);
00375 static tree storedecls (tree decls);
00376 static void store_parm_decls (int is_main_program);
00377 static tree start_decl (tree decl, bool is_top_level);
00378 static void start_function (tree name, tree type, int nested, int public);
00379 static void ffecom_file_ (const char *name);
00380 static void ffecom_close_include_ (FILE *f);
00381 static int ffecom_decode_include_option_ (char *spec);
00382 static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
00383 ffewhereColumn c);
00384
00385
00386
00387 static ffesymbol ffecom_primary_entry_ = NULL;
00388 static ffesymbol ffecom_nested_entry_ = NULL;
00389 static ffeinfoKind ffecom_primary_entry_kind_;
00390 static bool ffecom_primary_entry_is_proc_;
00391 static tree ffecom_outer_function_decl_;
00392 static tree ffecom_previous_function_decl_;
00393 static tree ffecom_which_entrypoint_decl_;
00394 static tree ffecom_float_zero_ = NULL_TREE;
00395 static tree ffecom_float_half_ = NULL_TREE;
00396 static tree ffecom_double_zero_ = NULL_TREE;
00397 static tree ffecom_double_half_ = NULL_TREE;
00398 static tree ffecom_func_result_;
00399 static tree ffecom_func_length_;
00400 static ffebld ffecom_list_blockdata_;
00401 static ffebld ffecom_list_common_;
00402 static ffebld ffecom_master_arglist_;
00403 static ffeinfoBasictype ffecom_master_bt_;
00404 static ffeinfoKindtype ffecom_master_kt_;
00405 static ffetargetCharacterSize ffecom_master_size_;
00406 static int ffecom_num_fns_ = 0;
00407 static int ffecom_num_entrypoints_ = 0;
00408 static bool ffecom_is_altreturning_ = FALSE;
00409 static tree ffecom_multi_type_node_;
00410 static tree ffecom_multi_retval_;
00411 static tree
00412 ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
00413 static bool ffecom_member_namelisted_;
00414 static bool ffecom_doing_entry_ = FALSE;
00415 static bool ffecom_transform_only_dummies_ = FALSE;
00416 static int ffecom_typesize_pointer_;
00417 static int ffecom_typesize_integer1_;
00418
00419
00420
00421 static tree ffecom_gfrt_[FFECOM_gfrt]
00422 =
00423 {
00424 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NULL_TREE,
00425 #include "com-rt.def"
00426 #undef DEFGFRT
00427 };
00428
00429
00430
00431 static const char *const ffecom_gfrt_name_[FFECOM_gfrt]
00432 =
00433 {
00434 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NAME,
00435 #include "com-rt.def"
00436 #undef DEFGFRT
00437 };
00438
00439
00440
00441 static const bool ffecom_gfrt_volatile_[FFECOM_gfrt]
00442 =
00443 {
00444 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) VOLATILE,
00445 #include "com-rt.def"
00446 #undef DEFGFRT
00447 };
00448
00449
00450
00451 static const bool ffecom_gfrt_complex_[FFECOM_gfrt]
00452 =
00453 {
00454 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) COMPLEX,
00455 #include "com-rt.def"
00456 #undef DEFGFRT
00457 };
00458
00459
00460
00461
00462 static const bool ffecom_gfrt_const_[FFECOM_gfrt]
00463 =
00464 {
00465 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) CONST,
00466 #include "com-rt.def"
00467 #undef DEFGFRT
00468 };
00469
00470
00471
00472 static const ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt]
00473 =
00474 {
00475 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) TYPE,
00476 #include "com-rt.def"
00477 #undef DEFGFRT
00478 };
00479
00480
00481
00482 static const char *const ffecom_gfrt_argstring_[FFECOM_gfrt]
00483 =
00484 {
00485 #define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) ARGS,
00486 #include "com-rt.def"
00487 #undef DEFGFRT
00488 };
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 #ifndef SIZE_TYPE
00499 #define SIZE_TYPE "long unsigned int"
00500 #endif
00501
00502 #define ffecom_concat_list_count_(catlist) ((catlist).count)
00503 #define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)])
00504 #define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen)
00505 #define ffecom_concat_list_minlen_(catlist) ((catlist).minlen)
00506
00507 #define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE)
00508 #define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE)
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 struct binding_level
00525 {
00526
00527
00528
00529 tree names;
00530
00531
00532
00533
00534 tree blocks;
00535
00536
00537
00538 tree this_block;
00539
00540
00541 struct binding_level *level_chain;
00542
00543
00544
00545
00546 int prep_state;
00547 };
00548
00549 #define NULL_BINDING_LEVEL (struct binding_level *) NULL
00550
00551
00552
00553 static struct binding_level *current_binding_level;
00554
00555
00556
00557 static struct binding_level *free_binding_level;
00558
00559
00560
00561
00562
00563 static struct binding_level *global_binding_level;
00564
00565
00566
00567 static const struct binding_level clear_binding_level
00568 =
00569 {NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
00570
00571
00572
00573 struct lang_identifier
00574 {
00575 struct tree_identifier ignore;
00576 tree global_value, local_value, label_value;
00577 bool invented;
00578 };
00579
00580
00581
00582
00583
00584
00585 #define IDENTIFIER_GLOBAL_VALUE(NODE) \
00586 (((struct lang_identifier *)(NODE))->global_value)
00587
00588
00589 #define IDENTIFIER_LOCAL_VALUE(NODE) \
00590 (((struct lang_identifier *)(NODE))->local_value)
00591
00592
00593 #define IDENTIFIER_LABEL_VALUE(NODE) \
00594 (((struct lang_identifier *)(NODE))->label_value)
00595
00596 #define IDENTIFIER_INVENTED(NODE) \
00597 (((struct lang_identifier *)(NODE))->invented)
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608 static tree named_labels;
00609
00610
00611
00612 static tree shadowed_labels;
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 static tree
00623 ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
00624 const char *array_name)
00625 {
00626 tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
00627 tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
00628 tree cond;
00629 tree die;
00630 tree args;
00631
00632 if (element == error_mark_node)
00633 return element;
00634
00635 if (TREE_TYPE (low) != TREE_TYPE (element))
00636 {
00637 if (TYPE_PRECISION (TREE_TYPE (low))
00638 > TYPE_PRECISION (TREE_TYPE (element)))
00639 element = convert (TREE_TYPE (low), element);
00640 else
00641 {
00642 low = convert (TREE_TYPE (element), low);
00643 if (high)
00644 high = convert (TREE_TYPE (element), high);
00645 }
00646 }
00647
00648 element = ffecom_save_tree (element);
00649 if (total_dims == 0)
00650 {
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669 if (dim)
00670 cond = ffecom_2 (LE_EXPR, integer_type_node, element, high);
00671 else
00672 cond = ffecom_2 (LE_EXPR, integer_type_node, low, element);
00673 }
00674 else
00675 {
00676
00677
00678 cond = ffecom_2 (LE_EXPR, integer_type_node,
00679 low,
00680 element);
00681 if (high)
00682 {
00683 cond = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
00684 cond,
00685 ffecom_2 (LE_EXPR, integer_type_node,
00686 element,
00687 high));
00688 }
00689 }
00690
00691 {
00692 int len;
00693 char *proc;
00694 char *var;
00695 tree arg3;
00696 tree arg2;
00697 tree arg1;
00698 tree arg4;
00699
00700 switch (total_dims)
00701 {
00702 case 0:
00703 var = concat (array_name, "[", (dim ? "end" : "start"),
00704 "-substring]", NULL);
00705 len = strlen (var) + 1;
00706 arg1 = build_string (len, var);
00707 free (var);
00708 break;
00709
00710 case 1:
00711 len = strlen (array_name) + 1;
00712 arg1 = build_string (len, array_name);
00713 break;
00714
00715 default:
00716 var = xmalloc (strlen (array_name) + 40);
00717 sprintf (var, "%s[subscript-%d-of-%d]",
00718 array_name,
00719 dim + 1, total_dims);
00720 len = strlen (var) + 1;
00721 arg1 = build_string (len, var);
00722 free (var);
00723 break;
00724 }
00725
00726 TREE_TYPE (arg1)
00727 = build_type_variant (build_array_type (char_type_node,
00728 build_range_type
00729 (integer_type_node,
00730 integer_one_node,
00731 build_int_2 (len, 0))),
00732 1, 0);
00733 TREE_CONSTANT (arg1) = 1;
00734 TREE_STATIC (arg1) = 1;
00735 arg1 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg1)),
00736 arg1);
00737
00738
00739
00740 arg2 = convert (ffecom_f2c_ftnint_type_node,
00741 ffecom_2 (MINUS_EXPR,
00742 TREE_TYPE (element),
00743 element,
00744 convert (TREE_TYPE (element),
00745 integer_one_node)));
00746
00747 proc = concat (input_filename, "/",
00748 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
00749 NULL);
00750 len = strlen (proc) + 1;
00751 arg3 = build_string (len, proc);
00752
00753 free (proc);
00754
00755 TREE_TYPE (arg3)
00756 = build_type_variant (build_array_type (char_type_node,
00757 build_range_type
00758 (integer_type_node,
00759 integer_one_node,
00760 build_int_2 (len, 0))),
00761 1, 0);
00762 TREE_CONSTANT (arg3) = 1;
00763 TREE_STATIC (arg3) = 1;
00764 arg3 = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg3)),
00765 arg3);
00766
00767 arg4 = convert (ffecom_f2c_ftnint_type_node,
00768 build_int_2 (lineno, 0));
00769
00770 arg1 = build_tree_list (NULL_TREE, arg1);
00771 arg2 = build_tree_list (NULL_TREE, arg2);
00772 arg3 = build_tree_list (NULL_TREE, arg3);
00773 arg4 = build_tree_list (NULL_TREE, arg4);
00774 TREE_CHAIN (arg3) = arg4;
00775 TREE_CHAIN (arg2) = arg3;
00776 TREE_CHAIN (arg1) = arg2;
00777
00778 args = arg1;
00779 }
00780 die = ffecom_call_gfrt (FFECOM_gfrtRANGE,
00781 args, NULL_TREE);
00782 TREE_SIDE_EFFECTS (die) = 1;
00783
00784 element = ffecom_3 (COND_EXPR,
00785 TREE_TYPE (element),
00786 cond,
00787 element,
00788 die);
00789
00790 return element;
00791 }
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 static tree
00802 ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
00803 {
00804 ffebld dims[FFECOM_dimensionsMAX];
00805 int i;
00806 int total_dims;
00807 int flatten = ffe_is_flatten_arrays ();
00808 int need_ptr;
00809 tree array;
00810 tree element;
00811 tree tree_type;
00812 tree tree_type_x;
00813 const char *array_name;
00814 ffetype type;
00815 ffebld list;
00816
00817 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)
00818 array_name = ffesymbol_text (ffebld_symter (ffebld_left (expr)));
00819 else
00820 array_name = "[expr?]";
00821
00822
00823
00824
00825 for (i = 0, list = ffebld_right (expr);
00826 list != NULL;
00827 ++i, list = ffebld_trail (list))
00828 {
00829 dims[i] = ffebld_head (list);
00830 type = ffeinfo_type (ffebld_basictype (dims[i]),
00831 ffebld_kindtype (dims[i]));
00832 if (! flatten
00833 && ffecom_typesize_pointer_ > ffecom_typesize_integer1_
00834 && ffetype_size (type) > ffecom_typesize_integer1_)
00835
00836
00837
00838
00839 flatten = 1;
00840 }
00841
00842 total_dims = i;
00843
00844 need_ptr = want_ptr || flatten;
00845
00846 if (! item)
00847 {
00848 if (need_ptr)
00849 item = ffecom_ptr_to_expr (ffebld_left (expr));
00850 else
00851 item = ffecom_expr (ffebld_left (expr));
00852
00853 if (item == error_mark_node)
00854 return item;
00855
00856 if (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING
00857 && ! mark_addressable (item))
00858 return error_mark_node;
00859 }
00860
00861 if (item == error_mark_node)
00862 return item;
00863
00864 if (need_ptr)
00865 {
00866 tree min;
00867
00868 for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
00869 i >= 0;
00870 --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array)))
00871 {
00872 min = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
00873 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
00874 if (flag_bounds_check)
00875 element = ffecom_subscript_check_ (array, element, i, total_dims,
00876 array_name);
00877 if (element == error_mark_node)
00878 return element;
00879
00880
00881
00882 tree_type = TREE_TYPE (element);
00883 tree_type_x = tree_type;
00884 if (tree_type
00885 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
00886 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
00887 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
00888
00889 if (TREE_TYPE (min) != tree_type_x)
00890 min = convert (tree_type_x, min);
00891 if (TREE_TYPE (element) != tree_type_x)
00892 element = convert (tree_type_x, element);
00893
00894 item = ffecom_2 (PLUS_EXPR,
00895 build_pointer_type (TREE_TYPE (array)),
00896 item,
00897 size_binop (MULT_EXPR,
00898 size_in_bytes (TREE_TYPE (array)),
00899 convert (sizetype,
00900 fold (build (MINUS_EXPR,
00901 tree_type_x,
00902 element, min)))));
00903 }
00904 if (! want_ptr)
00905 {
00906 item = ffecom_1 (INDIRECT_REF,
00907 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
00908 item);
00909 }
00910 }
00911 else
00912 {
00913 for (--i;
00914 i >= 0;
00915 --i)
00916 {
00917 array = TYPE_MAIN_VARIANT (TREE_TYPE (item));
00918
00919 element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
00920 if (flag_bounds_check)
00921 element = ffecom_subscript_check_ (array, element, i, total_dims,
00922 array_name);
00923 if (element == error_mark_node)
00924 return element;
00925
00926
00927
00928 tree_type = TREE_TYPE (element);
00929 tree_type_x = tree_type;
00930 if (tree_type
00931 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
00932 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
00933 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
00934
00935 element = convert (tree_type_x, element);
00936
00937 item = ffecom_2 (ARRAY_REF,
00938 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))),
00939 item,
00940 element);
00941 }
00942 }
00943
00944 return item;
00945 }
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957 static tree
00958 ffecom_stabilize_aggregate_ (tree ref)
00959 {
00960 tree result;
00961 enum tree_code code = TREE_CODE (ref);
00962
00963 switch (code)
00964 {
00965 case VAR_DECL:
00966 case PARM_DECL:
00967 case RESULT_DECL:
00968
00969 return ref;
00970
00971 case NOP_EXPR:
00972 case CONVERT_EXPR:
00973 case FLOAT_EXPR:
00974 case FIX_TRUNC_EXPR:
00975 case FIX_FLOOR_EXPR:
00976 case FIX_ROUND_EXPR:
00977 case FIX_CEIL_EXPR:
00978 result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0)));
00979 break;
00980
00981 case INDIRECT_REF:
00982 result = build_nt (INDIRECT_REF,
00983 stabilize_reference_1 (TREE_OPERAND (ref, 0)));
00984 break;
00985
00986 case COMPONENT_REF:
00987 result = build_nt (COMPONENT_REF,
00988 stabilize_reference (TREE_OPERAND (ref, 0)),
00989 TREE_OPERAND (ref, 1));
00990 break;
00991
00992 case BIT_FIELD_REF:
00993 result = build_nt (BIT_FIELD_REF,
00994 stabilize_reference (TREE_OPERAND (ref, 0)),
00995 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
00996 stabilize_reference_1 (TREE_OPERAND (ref, 2)));
00997 break;
00998
00999 case ARRAY_REF:
01000 result = build_nt (ARRAY_REF,
01001 stabilize_reference (TREE_OPERAND (ref, 0)),
01002 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
01003 break;
01004
01005 case COMPOUND_EXPR:
01006 result = build_nt (COMPOUND_EXPR,
01007 stabilize_reference_1 (TREE_OPERAND (ref, 0)),
01008 stabilize_reference (TREE_OPERAND (ref, 1)));
01009 break;
01010
01011 case RTL_EXPR:
01012 abort ();
01013
01014
01015 default:
01016 return save_expr (ref);
01017
01018 case ERROR_MARK:
01019 return error_mark_node;
01020 }
01021
01022 TREE_TYPE (result) = TREE_TYPE (ref);
01023 TREE_READONLY (result) = TREE_READONLY (ref);
01024 TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
01025 TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
01026
01027 return result;
01028 }
01029
01030
01031
01032
01033
01034 static tree
01035 ffecom_convert_to_complex_ (tree type, tree expr)
01036 {
01037 register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
01038 tree subtype;
01039
01040 assert (TREE_CODE (type) == RECORD_TYPE);
01041
01042 subtype = TREE_TYPE (TYPE_FIELDS (type));
01043
01044 if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
01045 {
01046 expr = convert (subtype, expr);
01047 return ffecom_2 (COMPLEX_EXPR, type, expr,
01048 convert (subtype, integer_zero_node));
01049 }
01050
01051 if (form == RECORD_TYPE)
01052 {
01053 tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr)));
01054 if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
01055 return expr;
01056 else
01057 {
01058 expr = save_expr (expr);
01059 return ffecom_2 (COMPLEX_EXPR,
01060 type,
01061 convert (subtype,
01062 ffecom_1 (REALPART_EXPR,
01063 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
01064 expr)),
01065 convert (subtype,
01066 ffecom_1 (IMAGPART_EXPR,
01067 TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))),
01068 expr)));
01069 }
01070 }
01071
01072 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
01073 error ("pointer value used where a complex was expected");
01074 else
01075 error ("aggregate value used where a complex was expected");
01076
01077 return ffecom_2 (COMPLEX_EXPR, type,
01078 convert (subtype, integer_zero_node),
01079 convert (subtype, integer_zero_node));
01080 }
01081
01082
01083
01084 static tree
01085 ffecom_convert_narrow_ (type, expr)
01086 tree type, expr;
01087 {
01088 register tree e = expr;
01089 register enum tree_code code = TREE_CODE (type);
01090
01091 if (type == TREE_TYPE (e)
01092 || TREE_CODE (e) == ERROR_MARK)
01093 return e;
01094 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
01095 return fold (build1 (NOP_EXPR, type, e));
01096 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
01097 || code == ERROR_MARK)
01098 return error_mark_node;
01099 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
01100 {
01101 assert ("void value not ignored as it ought to be" == NULL);
01102 return error_mark_node;
01103 }
01104 assert (code != VOID_TYPE);
01105 if ((code != RECORD_TYPE)
01106 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
01107 assert ("converting COMPLEX to REAL" == NULL);
01108 assert (code != ENUMERAL_TYPE);
01109 if (code == INTEGER_TYPE)
01110 {
01111 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
01112 && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)))
01113 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
01114 && (TYPE_PRECISION (type)
01115 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
01116 return fold (convert_to_integer (type, e));
01117 }
01118 if (code == POINTER_TYPE)
01119 {
01120 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
01121 return fold (convert_to_pointer (type, e));
01122 }
01123 if (code == REAL_TYPE)
01124 {
01125 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
01126 assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e)));
01127 return fold (convert_to_real (type, e));
01128 }
01129 if (code == COMPLEX_TYPE)
01130 {
01131 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
01132 assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
01133 return fold (convert_to_complex (type, e));
01134 }
01135 if (code == RECORD_TYPE)
01136 {
01137 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
01138
01139 assert (DECL_NAME (TYPE_FIELDS (type))
01140 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
01141 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
01142 <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
01143 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
01144 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
01145 return e;
01146 return fold (ffecom_convert_to_complex_ (type, e));
01147 }
01148
01149 assert ("conversion to non-scalar type requested" == NULL);
01150 return error_mark_node;
01151 }
01152
01153
01154
01155 static tree
01156 ffecom_convert_widen_ (type, expr)
01157 tree type, expr;
01158 {
01159 register tree e = expr;
01160 register enum tree_code code = TREE_CODE (type);
01161
01162 if (type == TREE_TYPE (e)
01163 || TREE_CODE (e) == ERROR_MARK)
01164 return e;
01165 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
01166 return fold (build1 (NOP_EXPR, type, e));
01167 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
01168 || code == ERROR_MARK)
01169 return error_mark_node;
01170 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
01171 {
01172 assert ("void value not ignored as it ought to be" == NULL);
01173 return error_mark_node;
01174 }
01175 assert (code != VOID_TYPE);
01176 if ((code != RECORD_TYPE)
01177 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
01178 assert ("narrowing COMPLEX to REAL" == NULL);
01179 assert (code != ENUMERAL_TYPE);
01180 if (code == INTEGER_TYPE)
01181 {
01182 assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE
01183 && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)))
01184 || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
01185 && (TYPE_PRECISION (type)
01186 == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e))))));
01187 return fold (convert_to_integer (type, e));
01188 }
01189 if (code == POINTER_TYPE)
01190 {
01191 assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE);
01192 return fold (convert_to_pointer (type, e));
01193 }
01194 if (code == REAL_TYPE)
01195 {
01196 assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE);
01197 assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e)));
01198 return fold (convert_to_real (type, e));
01199 }
01200 if (code == COMPLEX_TYPE)
01201 {
01202 assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE);
01203 assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e))));
01204 return fold (convert_to_complex (type, e));
01205 }
01206 if (code == RECORD_TYPE)
01207 {
01208 assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE);
01209
01210 assert (DECL_NAME (TYPE_FIELDS (type))
01211 == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e))));
01212 assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
01213 >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))));
01214 if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type)))
01215 == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e)))))
01216 return e;
01217 return fold (ffecom_convert_to_complex_ (type, e));
01218 }
01219
01220 assert ("conversion to non-scalar type requested" == NULL);
01221 return error_mark_node;
01222 }
01223
01224
01225
01226
01227
01228 static tree
01229 ffecom_make_complex_type_ (tree subtype)
01230 {
01231 tree type;
01232 tree realfield;
01233 tree imagfield;
01234
01235 if (ffe_is_emulate_complex ())
01236 {
01237 type = make_node (RECORD_TYPE);
01238 realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype);
01239 imagfield = ffecom_decl_field (type, realfield, "i", subtype);
01240 TYPE_FIELDS (type) = realfield;
01241 layout_type (type);
01242 }
01243 else
01244 {
01245 type = make_node (COMPLEX_TYPE);
01246 TREE_TYPE (type) = subtype;
01247 layout_type (type);
01248 }
01249
01250 return type;
01251 }
01252
01253
01254
01255
01256 static tree
01257 ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
01258 {
01259 tree bothparts;
01260
01261 if (ffe_is_emulate_complex ())
01262 {
01263 bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
01264 TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
01265 bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
01266 }
01267 else
01268 {
01269 bothparts = build_complex (type, realpart, imagpart);
01270 }
01271
01272 return bothparts;
01273 }
01274
01275 static tree
01276 ffecom_arglist_expr_ (const char *c, ffebld expr)
01277 {
01278 tree list;
01279 tree *plist = &list;
01280 tree trail = NULL_TREE;
01281 tree *ptrail = &trail;
01282 tree length;
01283 ffebld exprh;
01284 tree item;
01285 bool ptr = FALSE;
01286 tree wanted = NULL_TREE;
01287 static const char zed[] = "0";
01288
01289 if (c == NULL)
01290 c = &zed[0];
01291
01292 while (expr != NULL)
01293 {
01294 if (*c != '\0')
01295 {
01296 ptr = FALSE;
01297 if (*c == '&')
01298 {
01299 ptr = TRUE;
01300 ++c;
01301 }
01302 switch (*(c++))
01303 {
01304 case '\0':
01305 ptr = TRUE;
01306 wanted = NULL_TREE;
01307 break;
01308
01309 case 'a':
01310 assert (ptr);
01311 wanted = NULL_TREE;
01312 break;
01313
01314 case 'c':
01315 wanted = ffecom_f2c_complex_type_node;
01316 break;
01317
01318 case 'd':
01319 wanted = ffecom_f2c_doublereal_type_node;
01320 break;
01321
01322 case 'e':
01323 wanted = ffecom_f2c_doublecomplex_type_node;
01324 break;
01325
01326 case 'f':
01327 wanted = ffecom_f2c_real_type_node;
01328 break;
01329
01330 case 'i':
01331 wanted = ffecom_f2c_integer_type_node;
01332 break;
01333
01334 case 'j':
01335 wanted = ffecom_f2c_longint_type_node;
01336 break;
01337
01338 default:
01339 assert ("bad argstring code" == NULL);
01340 wanted = NULL_TREE;
01341 break;
01342 }
01343 }
01344
01345 exprh = ffebld_head (expr);
01346 if (exprh == NULL)
01347 wanted = NULL_TREE;
01348
01349 if ((wanted == NULL_TREE)
01350 || (ptr
01351 && (TYPE_MODE
01352 (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))]
01353 [ffeinfo_kindtype (ffebld_info (exprh))])
01354 == TYPE_MODE (wanted))))
01355 *plist
01356 = build_tree_list (NULL_TREE,
01357 ffecom_arg_ptr_to_expr (exprh,
01358 &length));
01359 else
01360 {
01361 item = ffecom_arg_expr (exprh, &length);
01362 item = ffecom_convert_widen_ (wanted, item);
01363 if (ptr)
01364 {
01365 item = ffecom_1 (ADDR_EXPR,
01366 build_pointer_type (TREE_TYPE (item)),
01367 item);
01368 }
01369 *plist
01370 = build_tree_list (NULL_TREE,
01371 item);
01372 }
01373
01374 plist = &TREE_CHAIN (*plist);
01375 expr = ffebld_trail (expr);
01376 if (length != NULL_TREE)
01377 {
01378 *ptrail = build_tree_list (NULL_TREE, length);
01379 ptrail = &TREE_CHAIN (*ptrail);
01380 }
01381 }
01382
01383
01384
01385
01386
01387 while (*c != '\0' && *c != '0')
01388 {
01389 if (*c == '&')
01390 ++c;
01391 else
01392 assert ("missing arg to run-time routine!" == NULL);
01393
01394 switch (*(c++))
01395 {
01396 case '\0':
01397 case 'a':
01398 case 'c':
01399 case 'd':
01400 case 'e':
01401 case 'f':
01402 case 'i':
01403 case 'j':
01404 break;
01405
01406 default:
01407 assert ("bad arg string code" == NULL);
01408 break;
01409 }
01410 *plist
01411 = build_tree_list (NULL_TREE,
01412 null_pointer_node);
01413 plist = &TREE_CHAIN (*plist);
01414 }
01415
01416 *plist = trail;
01417
01418 return list;
01419 }
01420
01421 static tree
01422 ffecom_widest_expr_type_ (ffebld list)
01423 {
01424 ffebld item;
01425 ffebld widest = NULL;
01426 ffetype type;
01427 ffetype widest_type = NULL;
01428 tree t;
01429
01430 for (; list != NULL; list = ffebld_trail (list))
01431 {
01432 item = ffebld_head (list);
01433 if (item == NULL)
01434 continue;
01435 if ((widest != NULL)
01436 && (ffeinfo_basictype (ffebld_info (item))
01437 != ffeinfo_basictype (ffebld_info (widest))))
01438 continue;
01439 type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)),
01440 ffeinfo_kindtype (ffebld_info (item)));
01441 if ((widest == FFEINFO_kindtypeNONE)
01442 || (ffetype_size (type)
01443 > ffetype_size (widest_type)))
01444 {
01445 widest = item;
01446 widest_type = type;
01447 }
01448 }
01449
01450 assert (widest != NULL);
01451 t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))]
01452 [ffeinfo_kindtype (ffebld_info (widest))];
01453 assert (t != NULL_TREE);
01454 return t;
01455 }
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466 static bool
01467 ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2 ATTRIBUTE_UNUSED)
01468 {
01469 ffesymbol sym;
01470 ffestorag st;
01471
01472 switch (ffebld_op (expr1))
01473 {
01474 case FFEBLD_opSYMTER:
01475 sym = ffebld_symter (expr1);
01476 break;
01477
01478 case FFEBLD_opARRAYREF:
01479 if (ffebld_op (ffebld_left (expr1)) != FFEBLD_opSYMTER)
01480 return FALSE;
01481 sym = ffebld_symter (ffebld_left (expr1));
01482 break;
01483
01484 default:
01485 return FALSE;
01486 }
01487
01488 if (ffesymbol_where (sym) != FFEINFO_whereCOMMON
01489 && (ffesymbol_where (sym) != FFEINFO_whereLOCAL
01490 || ! (st = ffesymbol_storage (sym))
01491 || ! ffestorag_parent (st)))
01492 return FALSE;
01493
01494
01495
01496 return TRUE;
01497 }
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507 static bool
01508 ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
01509 tree source_tree, ffebld source UNUSED,
01510 bool scalar_arg)
01511 {
01512 tree source_decl;
01513 tree source_offset;
01514 tree source_size;
01515 tree t;
01516
01517 if (source_tree == NULL_TREE)
01518 return FALSE;
01519
01520 switch (TREE_CODE (source_tree))
01521 {
01522 case ERROR_MARK:
01523 case IDENTIFIER_NODE:
01524 case INTEGER_CST:
01525 case REAL_CST:
01526 case COMPLEX_CST:
01527 case STRING_CST:
01528 case CONST_DECL:
01529 case VAR_DECL:
01530 case RESULT_DECL:
01531 case FIELD_DECL:
01532 case MINUS_EXPR:
01533 case MULT_EXPR:
01534 case TRUNC_DIV_EXPR:
01535 case CEIL_DIV_EXPR:
01536 case FLOOR_DIV_EXPR:
01537 case ROUND_DIV_EXPR:
01538 case TRUNC_MOD_EXPR:
01539 case CEIL_MOD_EXPR:
01540 case FLOOR_MOD_EXPR:
01541 case ROUND_MOD_EXPR:
01542 case RDIV_EXPR:
01543 case EXACT_DIV_EXPR:
01544 case FIX_TRUNC_EXPR:
01545 case FIX_CEIL_EXPR:
01546 case FIX_FLOOR_EXPR:
01547 case FIX_ROUND_EXPR:
01548 case FLOAT_EXPR:
01549 case NEGATE_EXPR:
01550 case MIN_EXPR:
01551 case MAX_EXPR:
01552 case ABS_EXPR:
01553 case FFS_EXPR:
01554 case LSHIFT_EXPR:
01555 case RSHIFT_EXPR:
01556 case LROTATE_EXPR:
01557 case RROTATE_EXPR:
01558 case BIT_IOR_EXPR:
01559 case BIT_XOR_EXPR:
01560 case BIT_AND_EXPR:
01561 case BIT_ANDTC_EXPR:
01562 case BIT_NOT_EXPR:
01563 case TRUTH_ANDIF_EXPR:
01564 case TRUTH_ORIF_EXPR:
01565 case TRUTH_AND_EXPR:
01566 case TRUTH_OR_EXPR:
01567 case TRUTH_XOR_EXPR:
01568 case TRUTH_NOT_EXPR:
01569 case LT_EXPR:
01570 case LE_EXPR:
01571 case GT_EXPR:
01572 case GE_EXPR:
01573 case EQ_EXPR:
01574 case NE_EXPR:
01575 case COMPLEX_EXPR:
01576 case CONJ_EXPR:
01577 case REALPART_EXPR:
01578 case IMAGPART_EXPR:
01579 case LABEL_EXPR:
01580 case COMPONENT_REF:
01581 return FALSE;
01582
01583 case COMPOUND_EXPR:
01584 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
01585 TREE_OPERAND (source_tree, 1), NULL,
01586 scalar_arg);
01587
01588 case MODIFY_EXPR:
01589 return ffecom_overlap_ (dest_decl, dest_offset, dest_size,
01590 TREE_OPERAND (source_tree, 0), NULL,
01591 scalar_arg);
01592
01593 case CONVERT_EXPR:
01594 case NOP_EXPR:
01595 case NON_LVALUE_EXPR:
01596 case PLUS_EXPR:
01597 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
01598 return TRUE;
01599
01600 ffecom_tree_canonize_ptr_ (&source_decl, &source_offset,
01601 source_tree);
01602 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
01603 break;
01604
01605 case COND_EXPR:
01606 return
01607 ffecom_overlap_ (dest_decl, dest_offset, dest_size,
01608 TREE_OPERAND (source_tree, 1), NULL,
01609 scalar_arg)
01610 || ffecom_overlap_ (dest_decl, dest_offset, dest_size,
01611 TREE_OPERAND (source_tree, 2), NULL,
01612 scalar_arg);
01613
01614
01615 case ADDR_EXPR:
01616 ffecom_tree_canonize_ref_ (&source_decl, &source_offset,
01617 &source_size,
01618 TREE_OPERAND (source_tree, 0));
01619 break;
01620
01621 case PARM_DECL:
01622 if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE)
01623 return TRUE;
01624
01625 source_decl = source_tree;
01626 source_offset = bitsize_zero_node;
01627 source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree)));
01628 break;
01629
01630 case SAVE_EXPR:
01631 case REFERENCE_EXPR:
01632 case PREDECREMENT_EXPR:
01633 case PREINCREMENT_EXPR:
01634 case POSTDECREMENT_EXPR:
01635 case POSTINCREMENT_EXPR:
01636 case INDIRECT_REF:
01637 case ARRAY_REF:
01638 case CALL_EXPR:
01639 default:
01640 return TRUE;
01641 }
01642
01643
01644
01645
01646 if (source_decl == NULL_TREE)
01647 return FALSE;
01648
01649 if (source_decl != dest_decl)
01650 return FALSE;
01651
01652 if (TREE_CODE (dest_size) == ERROR_MARK)
01653 return TRUE;
01654
01655
01656 t = ffecom_2 (LE_EXPR, integer_type_node,
01657 ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset),
01658 dest_offset,
01659 convert (TREE_TYPE (dest_offset),
01660 dest_size)),
01661 convert (TREE_TYPE (dest_offset),
01662 source_offset));
01663
01664 if (integer_onep (t))
01665 return FALSE;
01666
01667 if (!scalar_arg
01668 || (source_size == NULL_TREE)
01669 || (TREE_CODE (source_size) == ERROR_MARK)
01670 || integer_zerop (source_size))
01671 return TRUE;
01672
01673 t = ffecom_2 (LE_EXPR, integer_type_node,
01674 ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset),
01675 source_offset,
01676 convert (TREE_TYPE (source_offset),
01677 source_size)),
01678 convert (TREE_TYPE (source_offset),
01679 dest_offset));
01680
01681 if (integer_onep (t))
01682 return FALSE;
01683
01684 return TRUE;
01685 }
01686
01687
01688
01689
01690 static bool
01691 ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
01692 tree args, tree callee_commons,
01693 bool scalar_args)
01694 {
01695 tree arg;
01696 tree dest_decl;
01697 tree dest_offset;
01698 tree dest_size;
01699
01700 ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size,
01701 dest_tree);
01702
01703 if (dest_decl == NULL_TREE)
01704 return FALSE;
01705
01706
01707
01708
01709
01710 if ((TREE_CODE (dest_decl) == ERROR_MARK)
01711 || ((callee_commons != NULL_TREE)
01712 && TREE_PUBLIC (dest_decl)))
01713 return TRUE;
01714
01715 for (; args != NULL_TREE; args = TREE_CHAIN (args))
01716 {
01717 if (((arg = TREE_VALUE (args)) != NULL_TREE)
01718 && ffecom_overlap_ (dest_decl, dest_offset, dest_size,
01719 arg, NULL, scalar_args))
01720 return TRUE;
01721 }
01722
01723 return FALSE;
01724 }
01725
01726
01727
01728
01729
01730 static tree
01731 ffecom_build_f2c_string_ (int i, const char *s)
01732 {
01733 if (!ffe_is_f2c_library ())
01734 return build_string (i, s);
01735
01736 {
01737 char *tmp;
01738 const char *p;
01739 char *q;
01740 char space[34];
01741 tree t;
01742
01743 if (((size_t) i) > ARRAY_SIZE (space))
01744 tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i);
01745 else
01746 tmp = &space[0];
01747
01748 for (p = s, q = tmp; *p != '\0'; ++p, ++q)
01749 *q = TOUPPER (*p);
01750 *q = '\0';
01751
01752 t = build_string (i, tmp);
01753
01754 if (((size_t) i) > ARRAY_SIZE (space))
01755 malloc_kill_ks (malloc_pool_image (), tmp, i);
01756
01757 return t;
01758 }
01759 }
01760
01761
01762
01763
01764
01765
01766 static tree
01767 ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
01768 tree type, tree args, tree dest_tree,
01769 ffebld dest, bool *dest_used, tree callee_commons,
01770 bool scalar_args, tree hook)
01771 {
01772 tree item;
01773 tree tempvar;
01774
01775 if (dest_used != NULL)
01776 *dest_used = FALSE;
01777
01778 if (is_f2c_complex)
01779 {
01780 if ((dest_used == NULL)
01781 || (dest == NULL)
01782 || (ffeinfo_basictype (ffebld_info (dest))
01783 != FFEINFO_basictypeCOMPLEX)
01784 || (ffeinfo_kindtype (ffebld_info (dest)) != kt)
01785 || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type))
01786 || ffecom_args_overlapping_ (dest_tree, dest, args,
01787 callee_commons,
01788 scalar_args))
01789 {
01790 #ifdef HOHO
01791 tempvar = ffecom_make_tempvar (ffecom_tree_type
01792 [FFEINFO_basictypeCOMPLEX][kt],
01793 FFETARGET_charactersizeNONE,
01794 -1);
01795 #else
01796 tempvar = hook;
01797 assert (tempvar);
01798 #endif
01799 }
01800 else
01801 {
01802 *dest_used = TRUE;
01803 tempvar = dest_tree;
01804 type = NULL_TREE;
01805 }
01806
01807 item
01808 = build_tree_list (NULL_TREE,
01809 ffecom_1 (ADDR_EXPR,
01810 build_pointer_type (TREE_TYPE (tempvar)),
01811 tempvar));
01812 TREE_CHAIN (item) = args;
01813
01814 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
01815 item, NULL_TREE);
01816
01817 if (tempvar != dest_tree)
01818 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar);
01819 }
01820 else
01821 item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn,
01822 args, NULL_TREE);
01823
01824 if ((type != NULL_TREE) && (TREE_TYPE (item) != type))
01825 item = ffecom_convert_narrow_ (type, item);
01826
01827 return item;
01828 }
01829
01830
01831
01832
01833 static tree
01834 ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
01835 tree type, ffebld left, ffebld right,
01836 tree dest_tree, ffebld dest, bool *dest_used,
01837 tree callee_commons, bool scalar_args, bool ref, tree hook)
01838 {
01839 tree left_tree;
01840 tree right_tree;
01841 tree left_length;
01842 tree right_length;
01843
01844 if (ref)
01845 {
01846
01847 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
01848 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
01849 }
01850 else
01851 {
01852
01853 left_tree = ffecom_arg_expr (left, &left_length);
01854 right_tree = ffecom_arg_expr (right, &right_length);
01855 }
01856
01857
01858 left_tree = build_tree_list (NULL_TREE, left_tree);
01859 right_tree = build_tree_list (NULL_TREE, right_tree);
01860 TREE_CHAIN (left_tree) = right_tree;
01861
01862 if (left_length != NULL_TREE)
01863 {
01864 left_length = build_tree_list (NULL_TREE, left_length);
01865 TREE_CHAIN (right_tree) = left_length;
01866 }
01867
01868 if (right_length != NULL_TREE)
01869 {
01870 right_length = build_tree_list (NULL_TREE, right_length);
01871 if (left_length != NULL_TREE)
01872 TREE_CHAIN (left_length) = right_length;
01873 else
01874 TREE_CHAIN (right_tree) = right_length;
01875 }
01876
01877 return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree,
01878 dest_tree, dest, dest_used, callee_commons,
01879 scalar_args, hook);
01880 }
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892 static void
01893 ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
01894 {
01895 tree item;
01896 tree high;
01897 ffetargetCharacter1 val;
01898 ffetargetCharacterSize newlen;
01899
01900 switch (ffebld_op (expr))
01901 {
01902 case FFEBLD_opCONTER:
01903 val = ffebld_constant_character1 (ffebld_conter (expr));
01904 newlen = ffetarget_length_character1 (val);
01905 if (with_null)
01906 {
01907
01908 if (newlen != 0)
01909 ++newlen;
01910 }
01911 *length = build_int_2 (newlen, 0);
01912 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
01913 high = build_int_2 (newlen, 0);
01914 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
01915 item = build_string (newlen,
01916 ffetarget_text_character1 (val));
01917
01918 TREE_TYPE (item)
01919 = build_type_variant
01920 (build_array_type
01921 (char_type_node,
01922 build_range_type
01923 (ffecom_f2c_ftnlen_type_node,
01924 ffecom_f2c_ftnlen_one_node,
01925 high)),
01926 1, 0);
01927 TREE_CONSTANT (item) = 1;
01928 TREE_STATIC (item) = 1;
01929 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
01930 item);
01931 break;
01932
01933 case FFEBLD_opSYMTER:
01934 {
01935 ffesymbol s = ffebld_symter (expr);
01936
01937 item = ffesymbol_hook (s).decl_tree;
01938 if (item == NULL_TREE)
01939 {
01940 s = ffecom_sym_transform_ (s);
01941 item = ffesymbol_hook (s).decl_tree;
01942 }
01943 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
01944 {
01945 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
01946 *length = ffesymbol_hook (s).length_tree;
01947 else
01948 {
01949 *length = build_int_2 (ffesymbol_size (s), 0);
01950 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
01951 }
01952 }
01953 else if (item == error_mark_node)
01954 *length = error_mark_node;
01955 else
01956
01957 *length = NULL_TREE;
01958 if (!ffesymbol_hook (s).addr
01959 && (item != error_mark_node))
01960 item = ffecom_1 (ADDR_EXPR,
01961 build_pointer_type (TREE_TYPE (item)),
01962 item);
01963 }
01964 break;
01965
01966 case FFEBLD_opARRAYREF:
01967 {
01968 ffecom_char_args_ (&item, length, ffebld_left (expr));
01969
01970 if (item == error_mark_node || *length == error_mark_node)
01971 {
01972 item = *length = error_mark_node;
01973 break;
01974 }
01975
01976 item = ffecom_arrayref_ (item, expr, 1);
01977 }
01978 break;
01979
01980 case FFEBLD_opSUBSTR:
01981 {
01982 ffebld start;
01983 ffebld end;
01984 ffebld thing = ffebld_right (expr);
01985 tree start_tree;
01986 tree end_tree;
01987 const char *char_name;
01988 ffebld left_symter;
01989 tree array;
01990
01991 assert (ffebld_op (thing) == FFEBLD_opITEM);
01992 start = ffebld_head (thing);
01993 thing = ffebld_trail (thing);
01994 assert (ffebld_trail (thing) == NULL);
01995 end = ffebld_head (thing);
01996
01997
01998 for (left_symter = ffebld_left (expr);
01999 left_symter && ffebld_op (left_symter) == FFEBLD_opARRAYREF;
02000 left_symter = ffebld_left (left_symter))
02001 ;
02002 if (ffebld_op (left_symter) == FFEBLD_opSYMTER)
02003 char_name = ffesymbol_text (ffebld_symter (left_symter));
02004 else
02005 char_name = "[expr?]";
02006
02007 ffecom_char_args_ (&item, length, ffebld_left (expr));
02008
02009 if (item == error_mark_node || *length == error_mark_node)
02010 {
02011 item = *length = error_mark_node;
02012 break;
02013 }
02014
02015 array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item)));
02016
02017
02018
02019 if (start == NULL)
02020 {
02021 if (end == NULL)
02022 ;
02023 else
02024 {
02025 end_tree = ffecom_expr (end);
02026 if (flag_bounds_check)
02027 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
02028 char_name);
02029 end_tree = convert (ffecom_f2c_ftnlen_type_node,
02030 end_tree);
02031
02032 if (end_tree == error_mark_node)
02033 {
02034 item = *length = error_mark_node;
02035 break;
02036 }
02037
02038 *length = end_tree;
02039 }
02040 }
02041 else
02042 {
02043 start_tree = ffecom_expr (start);
02044 if (flag_bounds_check)
02045 start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
02046 char_name);
02047 start_tree = convert (ffecom_f2c_ftnlen_type_node,
02048 start_tree);
02049
02050 if (start_tree == error_mark_node)
02051 {
02052 item = *length = error_mark_node;
02053 break;
02054 }
02055
02056 start_tree = ffecom_save_tree (start_tree);
02057
02058 item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item),
02059 item,
02060 ffecom_2 (MINUS_EXPR,
02061 TREE_TYPE (start_tree),
02062 start_tree,
02063 ffecom_f2c_ftnlen_one_node));
02064
02065 if (end == NULL)
02066 {
02067 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
02068 ffecom_f2c_ftnlen_one_node,
02069 ffecom_2 (MINUS_EXPR,
02070 ffecom_f2c_ftnlen_type_node,
02071 *length,
02072 start_tree));
02073 }
02074 else
02075 {
02076 end_tree = ffecom_expr (end);
02077 if (flag_bounds_check)
02078 end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
02079 char_name);
02080 end_tree = convert (ffecom_f2c_ftnlen_type_node,
02081 end_tree);
02082
02083 if (end_tree == error_mark_node)
02084 {
02085 item = *length = error_mark_node;
02086 break;
02087 }
02088
02089 *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
02090 ffecom_f2c_ftnlen_one_node,
02091 ffecom_2 (MINUS_EXPR,
02092 ffecom_f2c_ftnlen_type_node,
02093 end_tree, start_tree));
02094 }
02095 }
02096 }
02097 break;
02098
02099 case FFEBLD_opFUNCREF:
02100 {
02101 ffesymbol s = ffebld_symter (ffebld_left (expr));
02102 tree tempvar;
02103 tree args;
02104 ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr));
02105 ffecomGfrt ix;
02106
02107 if (size == FFETARGET_charactersizeNONE)
02108
02109 size = 24;
02110
02111 *length = build_int_2 (size, 0);
02112 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
02113
02114 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
02115 == FFEINFO_whereINTRINSIC)
02116 {
02117 if (size == 1)
02118 {
02119
02120 item = ffecom_expr_intrinsic_ (expr, NULL_TREE,
02121 NULL, NULL);
02122 break;
02123 }
02124 ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr)));
02125 assert (ix != FFECOM_gfrt);
02126 item = ffecom_gfrt_tree_ (ix);
02127 }
02128 else
02129 {
02130 ix = FFECOM_gfrt;
02131 item = ffesymbol_hook (s).decl_tree;
02132 if (item == NULL_TREE)
02133 {
02134 s = ffecom_sym_transform_ (s);
02135 item = ffesymbol_hook (s).decl_tree;
02136 }
02137 if (item == error_mark_node)
02138 {
02139 item = *length = error_mark_node;
02140 break;
02141 }
02142
02143 if (!ffesymbol_hook (s).addr)
02144 item = ffecom_1_fn (item);
02145 }
02146
02147 #ifdef HOHO
02148 tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE);
02149 #else
02150 tempvar = ffebld_nonter_hook (expr);
02151 assert (tempvar);
02152 #endif
02153 tempvar = ffecom_1 (ADDR_EXPR,
02154 build_pointer_type (TREE_TYPE (tempvar)),
02155 tempvar);
02156
02157 args = build_tree_list (NULL_TREE, tempvar);
02158
02159 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
02160 TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr));
02161 else
02162 {
02163 TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length);
02164 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
02165 {
02166 TREE_CHAIN (TREE_CHAIN (args))
02167 = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix),
02168 ffebld_right (expr));
02169 }
02170 else
02171 {
02172 TREE_CHAIN (TREE_CHAIN (args))
02173 = ffecom_list_ptr_to_expr (ffebld_right (expr));
02174 }
02175 }
02176
02177 item = ffecom_3s (CALL_EXPR,
02178 TREE_TYPE (TREE_TYPE (TREE_TYPE (item))),
02179 item, args, NULL_TREE);
02180 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item,
02181 tempvar);
02182 }
02183 break;
02184
02185 case FFEBLD_opCONVERT:
02186
02187 ffecom_char_args_ (&item, length, ffebld_left (expr));
02188
02189 if (item == error_mark_node || *length == error_mark_node)
02190 {
02191 item = *length = error_mark_node;
02192 break;
02193 }
02194
02195 if ((ffebld_size_known (ffebld_left (expr))
02196 == FFETARGET_charactersizeNONE)
02197 || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr))))
02198 {
02199
02200 tree tempvar;
02201 tree args;
02202 tree newlen;
02203
02204 #ifdef HOHO
02205 tempvar = ffecom_make_tempvar (char_type_node,
02206 ffebld_size (expr), -1);
02207 #else
02208 tempvar = ffebld_nonter_hook (expr);
02209 assert (tempvar);
02210 #endif
02211 tempvar = ffecom_1 (ADDR_EXPR,
02212 build_pointer_type (TREE_TYPE (tempvar)),
02213 tempvar);
02214
02215 newlen = build_int_2 (ffebld_size (expr), 0);
02216 TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node;
02217
02218 args = build_tree_list (NULL_TREE, tempvar);
02219 TREE_CHAIN (args) = build_tree_list (NULL_TREE, item);
02220 TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen);
02221 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args)))
02222 = build_tree_list (NULL_TREE, *length);
02223
02224 item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args, NULL_TREE);
02225 TREE_SIDE_EFFECTS (item) = 1;
02226 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item),
02227 tempvar);
02228 *length = newlen;
02229 }
02230 else
02231 {
02232 *length = build_int_2 (ffebld_size (expr), 0);
02233 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
02234 }
02235 break;
02236
02237 default:
02238 assert ("bad op for single char arg expr" == NULL);
02239 item = NULL_TREE;
02240 break;
02241 }
02242
02243 *xitem = item;
02244 }
02245
02246
02247
02248
02249
02250
02251
02252
02253 static tree
02254 ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy)
02255 {
02256 if (TREE_CODE (type) == ERROR_MARK)
02257 return type;
02258
02259 if (TYPE_SIZE (type) == NULL_TREE)
02260 return type;
02261
02262 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
02263 return type;
02264
02265
02266
02267
02268
02269 if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
02270 || (!dummy && (TREE_INT_CST_HIGH (TYPE_SIZE (type)) > 3
02271 || TREE_OVERFLOW (TYPE_SIZE (type)))))
02272 {
02273 ffebad_start (FFEBAD_ARRAY_LARGE);
02274 ffebad_string (ffesymbol_text (s));
02275 ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s));
02276 ffebad_finish ();
02277
02278 return error_mark_node;
02279 }
02280
02281 return type;
02282 }
02283
02284
02285
02286
02287
02288 static tree
02289 ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s)
02290 {
02291 ffetargetCharacterSize sz = ffesymbol_size (s);
02292 tree highval;
02293 tree tlen;
02294 tree type = *xtype;
02295
02296 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
02297 tlen = NULL_TREE;
02298 else
02299 {
02300 if (ffesymbol_where (s) == FFEINFO_whereDUMMY)
02301 tlen = ffecom_get_invented_identifier ("__g77_length_%s",
02302 ffesymbol_text (s));
02303 else
02304 tlen = ffecom_get_invented_identifier ("__g77_%s", "length");
02305 tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node);
02306 DECL_ARTIFICIAL (tlen) = 1;
02307 }
02308
02309 if (sz == FFETARGET_charactersizeNONE)
02310 {
02311 assert (tlen != NULL_TREE);
02312 highval = variable_size (tlen);
02313 }
02314 else
02315 {
02316 highval = build_int_2 (sz, 0);
02317 TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node;
02318 }
02319
02320 type = build_array_type (type,
02321 build_range_type (ffecom_f2c_ftnlen_type_node,
02322 ffecom_f2c_ftnlen_one_node,
02323 highval));
02324
02325 *xtype = type;
02326 return tlen;
02327 }
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339 static ffecomConcatList_
02340 ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr,
02341 ffetargetCharacterSize max)
02342 {
02343 ffetargetCharacterSize sz;
02344
02345 recurse:
02346
02347 if (expr == NULL)
02348 return catlist;
02349
02350 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max))
02351 return catlist;
02352
02353 switch (ffebld_op (expr))
02354 {
02355 case FFEBLD_opCONTER:
02356 case FFEBLD_opSYMTER:
02357 case FFEBLD_opARRAYREF:
02358 case FFEBLD_opFUNCREF:
02359 case FFEBLD_opSUBSTR:
02360 case FFEBLD_opCONVERT:
02361
02362 if (catlist.count == catlist.max)
02363 {
02364 ffebld *newx;
02365 int newmax;
02366
02367 newmax = (catlist.max == 0) ? 8 : catlist.max * 2;
02368 newx = malloc_new_ks (malloc_pool_image (), "catlist",
02369 newmax * sizeof (newx[0]));
02370 if (catlist.max != 0)
02371 {
02372 memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0]));
02373 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
02374 catlist.max * sizeof (newx[0]));
02375 }
02376 catlist.max = newmax;
02377 catlist.exprs = newx;
02378 }
02379 if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE)
02380 catlist.minlen += sz;
02381 else
02382 ++catlist.minlen;
02383 if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE)
02384 catlist.maxlen = sz;
02385 else
02386 catlist.maxlen += sz;
02387 if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max))
02388 {
02389
02390 switch (ffebld_op (expr))
02391 {
02392 case FFEBLD_opCONTER:
02393 case FFEBLD_opSYMTER:
02394 case FFEBLD_opARRAYREF:
02395 case FFEBLD_opFUNCREF:
02396 case FFEBLD_opSUBSTR:
02397
02398 break;
02399
02400 default:
02401 assert ("op changed or inconsistent switches!" == NULL);
02402 break;
02403 }
02404 }
02405 catlist.exprs[catlist.count++] = expr;
02406 return catlist;
02407
02408 case FFEBLD_opPAREN:
02409 expr = ffebld_left (expr);
02410 goto recurse;
02411
02412 case FFEBLD_opCONCATENATE:
02413 catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max);
02414 expr = ffebld_right (expr);
02415 goto recurse;
02416
02417 #if 0
02418
02419 case FFEBLD_opCONVERT:
02420 expr = ffebld_left (expr);
02421 {
02422 ffetargetCharacterSize cmax;
02423
02424 cmax = catlist.len + ffebld_size_known (expr);
02425
02426 if ((max == FFETARGET_charactersizeNONE) || (max > cmax))
02427 max = cmax;
02428 }
02429 goto recurse;
02430 #endif
02431
02432 case FFEBLD_opANY:
02433 return catlist;
02434
02435 default:
02436 assert ("bad op in _gather_" == NULL);
02437 return catlist;
02438 }
02439 }
02440
02441
02442
02443
02444
02445
02446
02447
02448 static void
02449 ffecom_concat_list_kill_ (ffecomConcatList_ catlist)
02450 {
02451 if (catlist.max != 0)
02452 malloc_kill_ks (malloc_pool_image (), catlist.exprs,
02453 catlist.max * sizeof (catlist.exprs[0]));
02454 }
02455
02456
02457
02458
02459
02460
02461 static ffecomConcatList_
02462 ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max)
02463 {
02464 ffecomConcatList_ catlist;
02465
02466 catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0;
02467 return ffecom_concat_list_gather_ (catlist, expr, max);
02468 }
02469
02470
02471
02472
02473
02474 static void
02475 ffecom_debug_kludge_ (tree aggr, const char *aggr_type, ffesymbol member,
02476 tree member_type UNUSED, ffetargetOffset offset)
02477 {
02478 tree value;
02479 tree decl;
02480 int len;
02481 char *buff;
02482 char space[120];
02483 #if 0
02484 tree type_id;
02485
02486 for (type_id = member_type;
02487 TREE_CODE (type_id) != IDENTIFIER_NODE;
02488 )
02489 {
02490 switch (TREE_CODE (type_id))
02491 {
02492 case INTEGER_TYPE:
02493 case REAL_TYPE:
02494 type_id = TYPE_NAME (type_id);
02495 break;
02496
02497 case ARRAY_TYPE:
02498 case COMPLEX_TYPE:
02499 type_id = TREE_TYPE (type_id);
02500 break;
02501
02502 default:
02503 assert ("no IDENTIFIER_NODE for type!" == NULL);
02504 type_id = error_mark_node;
02505 break;
02506 }
02507 }
02508 #endif
02509
02510 if (ffecom_transform_only_dummies_
02511 || !ffe_is_debug_kludge ())
02512 return;
02513
02514 len = 60
02515 + strlen (aggr_type)
02516 + IDENTIFIER_LENGTH (DECL_NAME (aggr));
02517 #if 0
02518 + IDENTIFIER_LENGTH (type_id);
02519 #endif
02520
02521 if (((size_t) len) >= ARRAY_SIZE (space))
02522 buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1);
02523 else
02524 buff = &space[0];
02525
02526 sprintf (&buff[0], "At (%s) `%s' plus %ld bytes",
02527 aggr_type,
02528 IDENTIFIER_POINTER (DECL_NAME (aggr)),
02529 (long int) offset);
02530
02531 value = build_string (len, buff);
02532 TREE_TYPE (value)
02533 = build_type_variant (build_array_type (char_type_node,
02534 build_range_type
02535 (integer_type_node,
02536 integer_one_node,
02537 build_int_2 (strlen (buff), 0))),
02538 1, 0);
02539 decl = build_decl (VAR_DECL,
02540 ffecom_get_identifier_ (ffesymbol_text (member)),
02541 TREE_TYPE (value));
02542 TREE_CONSTANT (decl) = 1;
02543 TREE_STATIC (decl) = 1;
02544 DECL_INITIAL (decl) = error_mark_node;
02545 DECL_IN_SYSTEM_HEADER (decl) = 1;
02546 decl = start_decl (decl, FALSE);
02547 finish_decl (decl, value, FALSE);
02548
02549 if (buff != &space[0])
02550 malloc_kill_ks (malloc_pool_image (), buff, len + 1);
02551 }
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562 static void
02563 ffecom_do_entry_ (ffesymbol fn, int entrynum)
02564 {
02565 ffebld item;
02566 tree type;
02567 tree multi_retval;
02568 tree result;
02569 ffeinfoBasictype bt;
02570 ffeinfoKindtype kt;
02571 ffeglobal g;
02572 ffeglobalType gt;
02573 bool charfunc;
02574
02575 bool cmplxfunc;
02576 bool multi;
02577 bool altreturning = FALSE;
02578 int old_lineno = lineno;
02579 const char *old_input_filename = input_filename;
02580
02581 input_filename = ffesymbol_where_filename (fn);
02582 lineno = ffesymbol_where_filelinenum (fn);
02583
02584 ffecom_doing_entry_ = TRUE;
02585
02586 switch (ffecom_primary_entry_kind_)
02587 {
02588 case FFEINFO_kindFUNCTION:
02589
02590
02591
02592 gt = FFEGLOBAL_typeFUNC;
02593 bt = ffesymbol_basictype (fn);
02594 kt = ffesymbol_kindtype (fn);
02595 if (bt == FFEINFO_basictypeNONE)
02596 {
02597 ffeimplic_establish_symbol (fn);
02598 if (ffesymbol_funcresult (fn) != NULL)
02599 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
02600 bt = ffesymbol_basictype (fn);
02601 kt = ffesymbol_kindtype (fn);
02602 }
02603
02604 if (bt == FFEINFO_basictypeCHARACTER)
02605 charfunc = TRUE, cmplxfunc = FALSE;
02606 else if ((bt == FFEINFO_basictypeCOMPLEX)
02607 && ffesymbol_is_f2c (fn))
02608 charfunc = FALSE, cmplxfunc = TRUE;
02609 else
02610 charfunc = cmplxfunc = FALSE;
02611
02612 if (charfunc)
02613 type = ffecom_tree_fun_type_void;
02614 else if (ffesymbol_is_f2c (fn))
02615 type = ffecom_tree_fun_type[bt][kt];
02616 else
02617 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
02618
02619 if ((type == NULL_TREE)
02620 || (TREE_TYPE (type) == NULL_TREE))
02621 type = ffecom_tree_fun_type_void;
02622
02623 multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE);
02624 break;
02625
02626 case FFEINFO_kindSUBROUTINE:
02627 gt = FFEGLOBAL_typeSUBR;
02628 bt = FFEINFO_basictypeNONE;
02629 kt = FFEINFO_kindtypeNONE;
02630 if (ffecom_is_altreturning_)
02631 {
02632 for (item = ffesymbol_dummyargs (fn);
02633 item != NULL;
02634 item = ffebld_trail (item))
02635 {
02636 if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR)
02637 {
02638 altreturning = TRUE;
02639 break;
02640 }
02641 }
02642 if (altreturning)
02643 type = ffecom_tree_subr_type;
02644 else
02645 type = ffecom_tree_fun_type_void;
02646 }
02647 else
02648 type = ffecom_tree_fun_type_void;
02649 charfunc = FALSE;
02650 cmplxfunc = FALSE;
02651 multi = FALSE;
02652 break;
02653
02654 default:
02655 assert ("say what??" == NULL);
02656
02657 case FFEINFO_kindANY:
02658 gt = FFEGLOBAL_typeANY;
02659 bt = FFEINFO_basictypeNONE;
02660 kt = FFEINFO_kindtypeNONE;
02661 type = error_mark_node;
02662 charfunc = FALSE;
02663 cmplxfunc = FALSE;
02664 multi = FALSE;
02665 break;
02666 }
02667
02668
02669
02670
02671
02672
02673 start_function (ffecom_get_external_identifier_ (fn),
02674 type,
02675 0,
02676 1);
02677
02678 if (((g = ffesymbol_global (fn)) != NULL)
02679 && ((ffeglobal_type (g) == gt)
02680 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
02681 {
02682 ffeglobal_set_hook (g, current_function_decl);
02683 }
02684
02685
02686
02687 for (item = ffecom_master_arglist_;
02688 item != NULL;
02689 item = ffebld_trail (item))
02690 {
02691 ffebld arg;
02692 ffesymbol s;
02693
02694 arg = ffebld_head (item);
02695 if (ffebld_op (arg) != FFEBLD_opSYMTER)
02696 continue;
02697 s = ffebld_symter (arg);
02698 ffesymbol_hook (s).decl_tree = NULL_TREE;
02699 ffesymbol_hook (s).length_tree = NULL_TREE;
02700 }
02701
02702
02703
02704 if (charfunc || cmplxfunc)
02705 {
02706 tree type;
02707 tree length;
02708
02709 if (charfunc)
02710 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
02711 else
02712 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
02713
02714 result = ffecom_get_invented_identifier ("__g77_%s", "result");
02715
02716
02717
02718 if (charfunc)
02719 length = ffecom_char_enhance_arg_ (&type, fn);
02720 else
02721 length = NULL_TREE;
02722
02723 type = build_pointer_type (type);
02724 result = build_decl (PARM_DECL, result, type);
02725
02726 push_parm_decl (result);
02727 ffecom_func_result_ = result;
02728
02729 if (charfunc)
02730 {
02731 push_parm_decl (length);
02732 ffecom_func_length_ = length;
02733 }
02734 }
02735 else
02736 result = DECL_RESULT (current_function_decl);
02737
02738 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE);
02739
02740 store_parm_decls (0);
02741
02742 ffecom_start_compstmt ();
02743
02744 current_binding_level->prep_state = 2;
02745
02746
02747
02748 if (multi)
02749 {
02750 multi_retval = ffecom_get_invented_identifier ("__g77_%s",
02751 "multi_retval");
02752 multi_retval = build_decl (VAR_DECL, multi_retval,
02753 ffecom_multi_type_node_);
02754 multi_retval = start_decl (multi_retval, FALSE);
02755 finish_decl (multi_retval, NULL_TREE, FALSE);
02756 }
02757 else
02758 multi_retval = NULL_TREE;
02759
02760
02761
02762 {
02763 ffebld list;
02764 ffebld arg;
02765 ffesymbol s;
02766 tree arglist = NULL_TREE;
02767 tree *plist = &arglist;
02768 tree prepend;
02769 tree call;
02770 tree actarg;
02771 tree master_fn;
02772
02773
02774
02775 for (list = ffecom_master_arglist_;
02776 list != NULL;
02777 list = ffebld_trail (list))
02778 {
02779 arg = ffebld_head (list);
02780 if (ffebld_op (arg) != FFEBLD_opSYMTER)
02781 continue;
02782 s = ffebld_symter (arg);
02783 if (ffesymbol_hook (s).decl_tree == NULL_TREE
02784 || ffesymbol_hook (s).decl_tree == error_mark_node)
02785 actarg = null_pointer_node;
02786 else
02787 actarg = ffesymbol_hook (s).decl_tree;
02788 *plist = build_tree_list (NULL_TREE, actarg);
02789 plist = &TREE_CHAIN (*plist);
02790 }
02791
02792
02793
02794
02795 for (list = ffecom_master_arglist_;
02796 list != NULL;
02797 list = ffebld_trail (list))
02798 {
02799 arg = ffebld_head (list);
02800 if (ffebld_op (arg) != FFEBLD_opSYMTER)
02801 continue;
02802 s = ffebld_symter (arg);
02803 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
02804 continue;
02805 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
02806 continue;
02807 if (ffesymbol_hook (s).length_tree == NULL_TREE
02808 || ffesymbol_hook (s).length_tree == error_mark_node)
02809 actarg = ffecom_f2c_ftnlen_zero_node;
02810 else
02811 actarg = ffesymbol_hook (s).length_tree;
02812 *plist = build_tree_list (NULL_TREE, actarg);
02813 plist = &TREE_CHAIN (*plist);
02814 }
02815
02816
02817
02818 if (charfunc)
02819 {
02820 prepend = build_tree_list (NULL_TREE, ffecom_func_result_);
02821 TREE_CHAIN (prepend)
02822 = build_tree_list (NULL_TREE, ffecom_func_length_);
02823 TREE_CHAIN (TREE_CHAIN (prepend)) = arglist;
02824 arglist = prepend;
02825 }
02826
02827
02828
02829 if (multi)
02830 {
02831 prepend
02832 = build_tree_list (NULL_TREE,
02833 ffecom_1 (ADDR_EXPR,
02834 build_pointer_type (TREE_TYPE (multi_retval)),
02835 multi_retval));
02836 TREE_CHAIN (prepend) = arglist;
02837 arglist = prepend;
02838 }
02839
02840
02841
02842 prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0));
02843 TREE_CHAIN (prepend) = arglist;
02844 arglist = prepend;
02845
02846
02847
02848 master_fn = ffecom_1_fn (ffecom_previous_function_decl_);
02849 call = ffecom_3s (CALL_EXPR,
02850 TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))),
02851 master_fn, arglist, NULL_TREE);
02852
02853
02854
02855
02856 if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
02857 && !altreturning))
02858 {
02859 expand_expr_stmt (call);
02860 expand_null_return ();
02861 }
02862 else if (multi && cmplxfunc)
02863 {
02864 expand_expr_stmt (call);
02865 result
02866 = ffecom_1 (INDIRECT_REF,
02867 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
02868 result);
02869 result = ffecom_modify (NULL_TREE, result,
02870 ffecom_2 (COMPONENT_REF, TREE_TYPE (result),
02871 multi_retval,
02872 ffecom_multi_fields_[bt][kt]));
02873 expand_expr_stmt (result);
02874 expand_null_return ();
02875 }
02876 else if (multi)
02877 {
02878 expand_expr_stmt (call);
02879 result
02880 = ffecom_modify (NULL_TREE, result,
02881 convert (TREE_TYPE (result),
02882 ffecom_2 (COMPONENT_REF,
02883 ffecom_tree_type[bt][kt],
02884 multi_retval,
02885 ffecom_multi_fields_[bt][kt])));
02886 expand_return (result);
02887 }
02888 else if (cmplxfunc)
02889 {
02890 result
02891 = ffecom_1 (INDIRECT_REF,
02892 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))),
02893 result);
02894 result = ffecom_modify (NULL_TREE, result, call);
02895 expand_expr_stmt (result);
02896 expand_null_return ();
02897 }
02898 else
02899 {
02900 result = ffecom_modify (NULL_TREE,
02901 result,
02902 convert (TREE_TYPE (result),
02903 call));
02904 expand_return (result);
02905 }
02906 }
02907
02908 ffecom_end_compstmt ();
02909
02910 finish_function (0);
02911
02912 lineno = old_lineno;
02913 input_filename = old_input_filename;
02914
02915 ffecom_doing_entry_ = FALSE;
02916 }
02917
02918
02919
02920
02921
02922
02923
02924
02925 static tree
02926 ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
02927 bool *dest_used, bool assignp, bool widenp)
02928 {
02929 tree item;
02930 tree list;
02931 tree args;
02932 ffeinfoBasictype bt;
02933 ffeinfoKindtype kt;
02934 tree t;
02935 tree dt;
02936 tree tree_type, tree_type_x;
02937 tree left, right;
02938 ffesymbol s;
02939 enum tree_code code;
02940
02941 assert (expr != NULL);
02942
02943 if (dest_used != NULL)
02944 *dest_used = FALSE;
02945
02946 bt = ffeinfo_basictype (ffebld_info (expr));
02947 kt = ffeinfo_kindtype (ffebld_info (expr));
02948 tree_type = ffecom_tree_type[bt][kt];
02949
02950
02951 tree_type_x = NULL_TREE;
02952 if (widenp && tree_type
02953 && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT
02954 && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype))
02955 tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype);
02956
02957 switch (ffebld_op (expr))
02958 {
02959 case FFEBLD_opACCTER:
02960 {
02961 ffebitCount i;
02962 ffebit bits = ffebld_accter_bits (expr);
02963 ffetargetOffset source_offset = 0;
02964 ffetargetOffset dest_offset = ffebld_accter_pad (expr);
02965 tree purpose;
02966
02967 assert (dest_offset == 0
02968 || (bt == FFEINFO_basictypeCHARACTER
02969 && kt == FFEINFO_kindtypeCHARACTER1));
02970
02971 list = item = NULL;
02972 for (;;)
02973 {
02974 ffebldConstantUnion cu;
02975 ffebitCount length;
02976 bool value;
02977 ffebldConstantArray ca = ffebld_accter (expr);
02978
02979 ffebit_test (bits, source_offset, &value, &length);
02980 if (length == 0)
02981 break;
02982
02983 if (value)
02984 {
02985 for (i = 0; i < length; ++i)
02986 {
02987 cu = ffebld_constantarray_get (ca, bt, kt,
02988 source_offset + i);
02989
02990 t = ffecom_constantunion (&cu, bt, kt, tree_type);
02991
02992 if (i == 0
02993 && dest_offset != 0)
02994 purpose = build_int_2 (dest_offset, 0);
02995 else
02996 purpose = NULL_TREE;
02997
02998 if (list == NULL_TREE)
02999 list = item = build_tree_list (purpose, t);
03000 else
03001 {
03002 TREE_CHAIN (item) = build_tree_list (purpose, t);
03003 item = TREE_CHAIN (item);
03004 }
03005 }
03006 }
03007 source_offset += length;
03008 dest_offset += length;
03009 }
03010 }
03011
03012 item = build_int_2 ((ffebld_accter_size (expr)
03013 + ffebld_accter_pad (expr)) - 1, 0);
03014 ffebit_kill (ffebld_accter_bits (expr));
03015 TREE_TYPE (item) = ffecom_integer_type_node;
03016 item
03017 = build_array_type
03018 (tree_type,
03019 build_range_type (ffecom_integer_type_node,
03020 ffecom_integer_zero_node,
03021 item));
03022 list = build (CONSTRUCTOR, item, NULL_TREE, list);
03023 TREE_CONSTANT (list) = 1;
03024 TREE_STATIC (list) = 1;
03025 return list;
03026
03027 case FFEBLD_opARRTER:
03028 {
03029 ffetargetOffset i;
03030
03031 list = NULL_TREE;
03032 if (ffebld_arrter_pad (expr) == 0)
03033 item = NULL_TREE;
03034 else
03035 {
03036 assert (bt == FFEINFO_basictypeCHARACTER
03037 && kt == FFEINFO_kindtypeCHARACTER1);
03038
03039
03040 item = build_int_2 (ffebld_arrter_pad (expr), 0);
03041 }
03042
03043 for (i = 0; i < ffebld_arrter_size (expr); ++i)
03044 {
03045 ffebldConstantUnion cu
03046 = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i);
03047
03048 t = ffecom_constantunion (&cu, bt, kt, tree_type);
03049
03050 if (list == NULL_TREE)
03051
03052 list = item = build_tree_list (item, t);
03053 else
03054 {
03055 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
03056 item = TREE_CHAIN (item);
03057 }
03058 }
03059 }
03060
03061 item = build_int_2 ((ffebld_arrter_size (expr)
03062 + ffebld_arrter_pad (expr)) - 1, 0);
03063 TREE_TYPE (item) = ffecom_integer_type_node;
03064 item
03065 = build_array_type
03066 (tree_type,
03067 build_range_type (ffecom_integer_type_node,
03068 ffecom_integer_zero_node,
03069 item));
03070 list = build (CONSTRUCTOR, item, NULL_TREE, list);
03071 TREE_CONSTANT (list) = 1;
03072 TREE_STATIC (list) = 1;
03073 return list;
03074
03075 case FFEBLD_opCONTER:
03076 assert (ffebld_conter_pad (expr) == 0);
03077 item
03078 = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)),
03079 bt, kt, tree_type);
03080 return item;
03081
03082 case FFEBLD_opSYMTER:
03083 if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE)
03084 || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE))
03085 return ffecom_ptr_to_expr (expr);
03086 s = ffebld_symter (expr);
03087 t = ffesymbol_hook (s).decl_tree;
03088
03089 if (assignp)
03090 {
03091 if (ffe_is_ugly_assign ())
03092 {
03093
03094
03095
03096
03097
03098
03099
03100 if (t == NULL_TREE)
03101 {
03102 s = ffecom_sym_transform_ (s);
03103 t = ffesymbol_hook (s).decl_tree;
03104 assert (t != NULL_TREE);
03105 }
03106
03107 if (t == error_mark_node)
03108 return t;
03109
03110 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
03111 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
03112 {
03113 if (ffesymbol_hook (s).addr)
03114 t = ffecom_1 (INDIRECT_REF,
03115 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
03116 return t;
03117 }
03118
03119 if (ffesymbol_hook (s).assign_tree == NULL_TREE)
03120 {
03121
03122 ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling",
03123 FFEBAD_severityWARNING);
03124 ffebad_string (ffesymbol_text (s));
03125 ffebad_here (0, ffesymbol_where_line (s),
03126 ffesymbol_where_column (s));
03127 ffebad_finish ();
03128 }
03129 }
03130
03131
03132
03133
03134
03135
03136 if (t != NULL_TREE
03137 && TREE_CODE (t) == VAR_DECL)
03138 DECL_IN_SYSTEM_HEADER (t) = 1;
03139
03140 t = ffesymbol_hook (s).assign_tree;
03141 if (t == NULL_TREE)
03142 {
03143 s = ffecom_sym_transform_assign_ (s);
03144 t = ffesymbol_hook (s).assign_tree;
03145 assert (t != NULL_TREE);
03146 }
03147 }
03148 else
03149 {
03150 if (t == NULL_TREE)
03151 {
03152 s = ffecom_sym_transform_ (s);
03153 t = ffesymbol_hook (s).decl_tree;
03154 assert (t != NULL_TREE);
03155 }
03156 if (ffesymbol_hook (s).addr)
03157 t = ffecom_1 (INDIRECT_REF,
03158 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t);
03159 }
03160 return t;
03161
03162 case FFEBLD_opARRAYREF:
03163 return ffecom_arrayref_ (NULL_TREE, expr, 0);
03164
03165 case FFEBLD_opUPLUS:
03166 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
03167 return ffecom_1 (NOP_EXPR, tree_type, left);
03168
03169 case FFEBLD_opPAREN:
03170
03171 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
03172 return ffecom_1 (NOP_EXPR, tree_type, left);
03173
03174 case FFEBLD_opUMINUS:
03175 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
03176 if (tree_type_x)
03177 {
03178 tree_type = tree_type_x;
03179 left = convert (tree_type, left);
03180 }
03181 return ffecom_1 (NEGATE_EXPR, tree_type, left);
03182
03183 case FFEBLD_opADD:
03184 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
03185 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
03186 if (tree_type_x)
03187 {
03188 tree_type = tree_type_x;
03189 left = convert (tree_type, left);
03190 right = convert (tree_type, right);
03191 }
03192 return ffecom_2 (PLUS_EXPR, tree_type, left, right);
03193
03194 case FFEBLD_opSUBTRACT:
03195 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
03196 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
03197 if (tree_type_x)
03198 {
03199 tree_type = tree_type_x;
03200 left = convert (tree_type, left);
03201 right = convert (tree_type, right);
03202 }
03203 return ffecom_2 (MINUS_EXPR, tree_type, left, right);
03204
03205 case FFEBLD_opMULTIPLY:
03206 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
03207 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
03208 if (tree_type_x)
03209 {
03210 tree_type = tree_type_x;
03211 left = convert (tree_type, left);
03212 right = convert (tree_type, right);
03213 }
03214 return ffecom_2 (MULT_EXPR, tree_type, left, right);
03215
03216 case FFEBLD_opDIVIDE:
03217 left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp);
03218 right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp);
03219 if (tree_type_x)
03220 {
03221 tree_type = tree_type_x;
03222 left = convert (tree_type, left);
03223 right = convert (tree_type, right);
03224 }
03225 return ffecom_tree_divide_ (tree_type, left, right,
03226 dest_tree, dest, dest_used,
03227 ffebld_nonter_hook (expr));
03228
03229 case FFEBLD_opPOWER:
03230 {
03231 ffebld left = ffebld_left (expr);
03232 ffebld right = ffebld_right (expr);
03233 ffecomGfrt code;
03234 ffeinfoKindtype rtkt;
03235 ffeinfoKindtype ltkt;
03236 bool ref = TRUE;
03237
03238 switch (ffeinfo_basictype (ffebld_info (right)))
03239 {
03240
03241 case FFEINFO_basictypeINTEGER:
03242 if (1 || optimize)
03243 {
03244 item = ffecom_expr_power_integer_ (expr);
03245 if (item != NULL_TREE)
03246 return item;
03247 }
03248
03249 rtkt = FFEINFO_kindtypeINTEGER1;
03250 switch (ffeinfo_basictype (ffebld_info (left)))
03251 {
03252 case FFEINFO_basictypeINTEGER:
03253 if ((ffeinfo_kindtype (ffebld_info (left))
03254 == FFEINFO_kindtypeINTEGER4)
03255 || (ffeinfo_kindtype (ffebld_info (right))
03256 == FFEINFO_kindtypeINTEGER4))
03257 {
03258 code = FFECOM_gfrtPOW_QQ;
03259 ltkt = FFEINFO_kindtypeINTEGER4;
03260 rtkt = FFEINFO_kindtypeINTEGER4;
03261 }
03262 else
03263 {
03264 code = FFECOM_gfrtPOW_II;
03265 ltkt = FFEINFO_kindtypeINTEGER1;
03266 }
03267 break;
03268
03269 case FFEINFO_basictypeREAL:
03270 if (ffeinfo_kindtype (ffebld_info (left))
03271 == FFEINFO_kindtypeREAL1)
03272 {
03273 code = FFECOM_gfrtPOW_RI;
03274 ltkt = FFEINFO_kindtypeREAL1;
03275 }
03276 else
03277 {
03278 code = FFECOM_gfrtPOW_DI;
03279 ltkt = FFEINFO_kindtypeREAL2;
03280 }
03281 break;
03282
03283 case FFEINFO_basictypeCOMPLEX:
03284 if (ffeinfo_kindtype (ffebld_info (left))
03285 == FFEINFO_kindtypeREAL1)
03286 {
03287 code = FFECOM_gfrtPOW_CI;
03288 ltkt = FFEINFO_kindtypeREAL1;
03289 }
03290 else
03291 {
03292 code = FFECOM_gfrtPOW_ZI;
03293 ltkt = FFEINFO_kindtypeREAL2;
03294 }
03295 break;
03296
03297 default:
03298 assert ("bad pow_*i" == NULL);
03299 code = FFECOM_gfrtPOW_CI;
03300 ltkt = FFEINFO_kindtypeREAL1;
03301 break;
03302 }
03303 if (ffeinfo_kindtype (ffebld_info (left)) != ltkt)
03304 left = ffeexpr_convert (left, NULL, NULL,
03305 ffeinfo_basictype (ffebld_info (left)),
03306 ltkt, 0,
03307 FFETARGET_charactersizeNONE,
03308 FFEEXPR_contextLET);
03309 if (ffeinfo_kindtype (ffebld_info (right)) != rtkt)
03310 right = ffeexpr_convert (right, NULL, NULL,
03311 FFEINFO_basictypeINTEGER,
03312 rtkt, 0,
03313 FFETARGET_charactersizeNONE,
03314 FFEEXPR_contextLET);
03315 break;
03316
03317 case FFEINFO_basictypeREAL:
03318 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
03319 left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL,
03320 FFEINFO_kindtypeREALDOUBLE, 0,
03321 FFETARGET_charactersizeNONE,
03322 FFEEXPR_contextLET);
03323 if (ffeinfo_kindtype (ffebld_info (right))
03324 == FFEINFO_kindtypeREAL1)
03325 right = ffeexpr_convert (right, NULL, NULL,
03326 FFEINFO_basictypeREAL,
03327 FFEINFO_kindtypeREALDOUBLE, 0,
03328 FFETARGET_charactersizeNONE,
03329 FFEEXPR_contextLET);
03330
03331
03332 code = FFECOM_gfrtL_POW;
03333
03334 ref = FALSE;
03335 break;
03336
03337 case FFEINFO_basictypeCOMPLEX:
03338 if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1)
03339 left = ffeexpr_convert (left, NULL, NULL,
03340 FFEINFO_basictypeCOMPLEX,
03341 FFEINFO_kindtypeREALDOUBLE, 0,
03342 FFETARGET_charactersizeNONE,
03343 FFEEXPR_contextLET);
03344 if (ffeinfo_kindtype (ffebld_info (right))
03345 == FFEINFO_kindtypeREAL1)
03346 right = ffeexpr_convert (right, NULL, NULL,
03347 FFEINFO_basictypeCOMPLEX,
03348 FFEINFO_kindtypeREALDOUBLE, 0,
03349 FFETARGET_charactersizeNONE,
03350 FFEEXPR_contextLET);
03351 code = FFECOM_gfrtPOW_ZZ;
03352 ref = TRUE;
03353 break;
03354
03355 default:
03356 assert ("bad pow_x*" == NULL);
03357 code = FFECOM_gfrtPOW_II;
03358 break;
03359 }
03360 return ffecom_call_binop_ (ffecom_gfrt_tree_ (code),
03361 ffecom_gfrt_kindtype (code),
03362 (ffe_is_f2c_library ()
03363 && ffecom_gfrt_complex_[code]),
03364 tree_type, left, right,
03365 dest_tree, dest, dest_used,
03366 NULL_TREE, FALSE, ref,
03367 ffebld_nonter_hook (expr));
03368 }
03369
03370 case FFEBLD_opNOT:
03371 switch (bt)
03372 {
03373 case FFEINFO_basictypeLOGICAL:
03374 item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr)));
03375 return convert (tree_type, item);
03376
03377 case FFEINFO_basictypeINTEGER:
03378 return ffecom_1 (BIT_NOT_EXPR, tree_type,
03379 ffecom_expr (ffebld_left (expr)));
03380
03381 default:
03382 assert ("NOT bad basictype" == NULL);
03383
03384 case FFEINFO_basictypeANY:
03385 return error_mark_node;
03386 }
03387 break;
03388
03389 case FFEBLD_opFUNCREF:
03390 assert (ffeinfo_basictype (ffebld_info (expr))
03391 != FFEINFO_basictypeCHARACTER);
03392
03393 case FFEBLD_opSUBRREF:
03394 if (ffeinfo_where (ffebld_info (ffebld_left (expr)))
03395 == FFEINFO_whereINTRINSIC)
03396 {
03397 item = ffecom_expr_intrinsic_ (expr, dest_tree, dest,
03398 dest_used);
03399 return item;
03400 }
03401 s = ffebld_symter (ffebld_left (expr));
03402 dt = ffesymbol_hook (s).decl_tree;
03403 if (dt == NULL_TREE)
03404 {
03405 s = ffecom_sym_transform_ (s);
03406 dt = ffesymbol_hook (s).decl_tree;
03407 }
03408 if (dt == error_mark_node)
03409 return dt;
03410
03411 if (ffesymbol_hook (s).addr)
03412 item = dt;
03413 else
03414 item = ffecom_1_fn (dt);
03415
03416 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT)
03417 args = ffecom_list_expr (ffebld_right (expr));
03418 else
03419 args = ffecom_list_ptr_to_expr (ffebld_right (expr));
03420
03421 if (args == error_mark_node)
03422 return error_mark_node;
03423
03424 item = ffecom_call_ (item, kt,
03425 ffesymbol_is_f2c (s)
03426 && (bt == FFEINFO_basictypeCOMPLEX)
03427 && (ffesymbol_where (s)
03428 != FFEINFO_whereCONSTANT),
03429 tree_type,
03430 args,
03431 dest_tree, dest, dest_used,
03432 error_mark_node, FALSE,
03433 ffebld_nonter_hook (expr));
03434 TREE_SIDE_EFFECTS (item) = 1;
03435 return item;
03436
03437 case FFEBLD_opAND:
03438 switch (bt)
03439 {
03440 case FFEINFO_basictypeLOGICAL:
03441 item
03442 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
03443 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
03444 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
03445 return convert (tree_type, item);
03446
03447 case FFEINFO_basictypeINTEGER:
03448 return ffecom_2 (BIT_AND_EXPR, tree_type,
03449 ffecom_expr (ffebld_left (expr)),
03450 ffecom_expr (ffebld_right (expr)));
03451
03452 default:
03453 assert ("AND bad basictype" == NULL);
03454
03455 case FFEINFO_basictypeANY:
03456 return error_mark_node;
03457 }
03458 break;
03459
03460 case FFEBLD_opOR:
03461 switch (bt)
03462 {
03463 case FFEINFO_basictypeLOGICAL:
03464 item
03465 = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
03466 ffecom_truth_value (ffecom_expr (ffebld_left (expr))),
03467 ffecom_truth_value (ffecom_expr (ffebld_right (expr))));
03468 return convert (tree_type, item);
03469
03470 case FFEINFO_basictypeINTEGER:
03471 return ffecom_2 (BIT_IOR_EXPR, tree_type,
03472 ffecom_expr (ffebld_left (expr)),
03473 ffecom_expr (ffebld_right (expr)));
03474
03475 default:
03476 assert ("OR bad basictype" == NULL);
03477
03478 case FFEINFO_basictypeANY:
03479 return error_mark_node;
03480 }
03481 break;
03482
03483 case FFEBLD_opXOR:
03484 case FFEBLD_opNEQV:
03485 switch (bt)
03486 {
03487 case FFEINFO_basictypeLOGICAL:
03488 item
03489 = ffecom_2 (NE_EXPR, integer_type_node,
03490 ffecom_expr (ffebld_left (expr)),
03491 ffecom_expr (ffebld_right (expr)));
03492 return convert (tree_type, ffecom_truth_value (item));
03493
03494 case FFEINFO_basictypeINTEGER:
03495 return ffecom_2 (BIT_XOR_EXPR, tree_type,
03496 ffecom_expr (ffebld_left (expr)),
03497 ffecom_expr (ffebld_right (expr)));
03498
03499 default:
03500 assert ("XOR/NEQV bad basictype" == NULL);
03501
03502 case FFEINFO_basictypeANY:
03503 return error_mark_node;
03504 }
03505 break;
03506
03507 case FFEBLD_opEQV:
03508 switch (bt)
03509 {
03510 case FFEINFO_basictypeLOGICAL:
03511 item
03512 = ffecom_2 (EQ_EXPR, integer_type_node,
03513 ffecom_expr (ffebld_left (expr)),
03514 ffecom_expr (ffebld_right (expr)));
03515 return convert (tree_type, ffecom_truth_value (item));
03516
03517 case FFEINFO_basictypeINTEGER:
03518 return
03519 ffecom_1 (BIT_NOT_EXPR, tree_type,
03520 ffecom_2 (BIT_XOR_EXPR, tree_type,
03521 ffecom_expr (ffebld_left (expr)),
03522 ffecom_expr (ffebld_right (expr))));
03523
03524 default:
03525 assert ("EQV bad basictype" == NULL);
03526
03527 case FFEINFO_basictypeANY:
03528 return error_mark_node;
03529 }
03530 break;
03531
03532 case FFEBLD_opCONVERT:
03533 if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY)
03534 return error_mark_node;
03535
03536 switch (bt)
03537 {
03538 case FFEINFO_basictypeLOGICAL:
03539 case FFEINFO_basictypeINTEGER:
03540 case FFEINFO_basictypeREAL:
03541 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
03542
03543 case FFEINFO_basictypeCOMPLEX:
03544 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
03545 {
03546 case FFEINFO_basictypeINTEGER:
03547 case FFEINFO_basictypeLOGICAL:
03548 case FFEINFO_basictypeREAL:
03549 item = ffecom_expr (ffebld_left (expr));
03550 if (item == error_mark_node)
03551 return error_mark_node;
03552
03553
03554 item = convert (tree_type, item);
03555 return item;
03556
03557 case FFEINFO_basictypeCOMPLEX:
03558 return convert (tree_type, ffecom_expr (ffebld_left (expr)));
03559
03560 default:
03561 assert ("CONVERT COMPLEX bad basictype" == NULL);
03562
03563 case FFEINFO_basictypeANY:
03564 return error_mark_node;
03565 }
03566 break;
03567
03568 default:
03569 assert ("CONVERT bad basictype" == NULL);
03570
03571 case FFEINFO_basictypeANY:
03572 return error_mark_node;
03573 }
03574 break;
03575
03576 case FFEBLD_opLT:
03577 code = LT_EXPR;
03578 goto relational;
03579
03580 case FFEBLD_opLE:
03581 code = LE_EXPR;
03582 goto relational;
03583
03584 case FFEBLD_opEQ:
03585 code = EQ_EXPR;
03586 goto relational;
03587
03588 case FFEBLD_opNE:
03589 code = NE_EXPR;
03590 goto relational;
03591
03592 case FFEBLD_opGT:
03593 code = GT_EXPR;
03594 goto relational;
03595
03596 case FFEBLD_opGE:
03597 code = GE_EXPR;
03598
03599 relational:
03600 switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr))))
03601 {
03602 case FFEINFO_basictypeLOGICAL:
03603 case FFEINFO_basictypeINTEGER:
03604 case FFEINFO_basictypeREAL:
03605 item = ffecom_2 (code, integer_type_node,
03606 ffecom_expr (ffebld_left (expr)),
03607 ffecom_expr (ffebld_right (expr)));
03608 return convert (tree_type, item);
03609
03610 case FFEINFO_basictypeCOMPLEX:
03611 assert (code == EQ_EXPR || code == NE_EXPR);
03612 {
03613 tree real_type;
03614 tree arg1 = ffecom_expr (ffebld_left (expr));
03615 tree arg2 = ffecom_expr (ffebld_right (expr));
03616
03617 if (arg1 == error_mark_node || arg2 == error_mark_node)
03618 return error_mark_node;
03619
03620 arg1 = ffecom_save_tree (arg1);
03621 arg2 = ffecom_save_tree (arg2);
03622
03623 if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE)
03624 {
03625 real_type = TREE_TYPE (TREE_TYPE (arg1));
03626 assert (real_type == TREE_TYPE (TREE_TYPE (arg2)));
03627 }
03628 else
03629 {
03630 real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1)));
03631 assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2))));
03632 }
03633
03634 item
03635 = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
03636 ffecom_2 (EQ_EXPR, integer_type_node,
03637 ffecom_1 (REALPART_EXPR, real_type, arg1),
03638 ffecom_1 (REALPART_EXPR, real_type, arg2)),
03639 ffecom_2 (EQ_EXPR, integer_type_node,
03640 ffecom_1 (IMAGPART_EXPR, real_type, arg1),
03641 ffecom_1 (IMAGPART_EXPR, real_type,
03642 arg2)));
03643 if (code == EQ_EXPR)
03644 item = ffecom_truth_value (item);
03645 else
03646 item = ffecom_truth_value_invert (item);
03647 return convert (tree_type, item);
03648 }
03649
03650 case FFEINFO_basictypeCHARACTER:
03651 {
03652 ffebld left = ffebld_left (expr);
03653 ffebld right = ffebld_right (expr);
03654 tree left_tree;
03655 tree right_tree;
03656 tree left_length;
03657 tree right_length;
03658
03659
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669
03670
03671 while (ffebld_op (left) == FFEBLD_opCONVERT)
03672 left = ffebld_left (left);
03673 while (ffebld_op (right) == FFEBLD_opCONVERT)
03674 right = ffebld_left (right);
03675
03676 left_tree = ffecom_arg_ptr_to_expr (left, &left_length);
03677 right_tree = ffecom_arg_ptr_to_expr (right, &right_length);
03678
03679 if (left_tree == error_mark_node || left_length == error_mark_node
03680 || right_tree == error_mark_node
03681 || right_length == error_mark_node)
03682 return error_mark_node;
03683
03684 if ((ffebld_size_known (left) == 1)
03685 && (ffebld_size_known (right) == 1))
03686 {
03687 left_tree
03688 = ffecom_1 (INDIRECT_REF,
03689 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
03690 left_tree);
03691 right_tree
03692 = ffecom_1 (INDIRECT_REF,
03693 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
03694 right_tree);
03695
03696 item
03697 = ffecom_2 (code, integer_type_node,
03698 ffecom_2 (ARRAY_REF,
03699 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))),
03700 left_tree,
03701 integer_one_node),
03702 ffecom_2 (ARRAY_REF,
03703 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))),
03704 right_tree,
03705 integer_one_node));
03706 }
03707 else
03708 {
03709 item = build_tree_list (NULL_TREE, left_tree);
03710 TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree);
03711 TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE,
03712 left_length);
03713 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
03714 = build_tree_list (NULL_TREE, right_length);
03715 item = ffecom_call_gfrt (FFECOM_gfrtCMP, item, NULL_TREE);
03716 item = ffecom_2 (code, integer_type_node,
03717 item,
03718 convert (TREE_TYPE (item),
03719 integer_zero_node));
03720 }
03721 item = convert (tree_type, item);
03722 }
03723
03724 return item;
03725
03726 default:
03727 assert ("relational bad basictype" == NULL);
03728
03729 case FFEINFO_basictypeANY:
03730 return error_mark_node;
03731 }
03732 break;
03733
03734 case FFEBLD_opPERCENT_LOC:
03735 item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list);
03736 return convert (tree_type, item);
03737
03738 case FFEBLD_opPERCENT_VAL:
03739 item = ffecom_arg_expr (ffebld_left (expr), &list);
03740 return convert (tree_type, item);
03741
03742 case FFEBLD_opITEM:
03743 case FFEBLD_opSTAR:
03744 case FFEBLD_opBOUNDS:
03745 case FFEBLD_opREPEAT:
03746 case FFEBLD_opLABTER:
03747 case FFEBLD_opLABTOK:
03748 case FFEBLD_opIMPDO:
03749 case FFEBLD_opCONCATENATE:
03750 case FFEBLD_opSUBSTR:
03751 default:
03752 assert ("bad op" == NULL);
03753
03754 case FFEBLD_opANY:
03755 return error_mark_node;
03756 }
03757
03758 #if 1
03759 assert ("didn't think anything got here anymore!!" == NULL);
03760 #else
03761 switch (ffebld_arity (expr))
03762 {
03763 case 2:
03764 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
03765 TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr));
03766 if (TREE_OPERAND (item, 0) == error_mark_node
03767 || TREE_OPERAND (item, 1) == error_mark_node)
03768 return error_mark_node;
03769 break;
03770
03771 case 1:
03772 TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr));
03773 if (TREE_OPERAND (item, 0) == error_mark_node)
03774 return error_mark_node;
03775 break;
03776
03777 default:
03778 break;
03779 }
03780
03781 return fold (item);
03782 #endif
03783 }
03784
03785
03786
03787
03788
03789
03790
03791 static tree
03792 ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
03793 ffebld dest, bool *dest_used)
03794 {
03795 tree expr_tree;
03796 tree saved_expr1;
03797 tree saved_expr2;
03798 ffeinfoBasictype bt;
03799 ffeinfoKindtype kt;
03800 tree tree_type;
03801 tree arg1_type;
03802 tree real_type;
03803 tree tempvar;
03804 ffebld list = ffebld_right (expr);
03805 ffebld arg1;
03806 ffebld arg2;
03807 ffebld arg3;
03808 ffeintrinImp codegen_imp;
03809 ffecomGfrt gfrt;
03810
03811 assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER);
03812
03813 if (dest_used != NULL)
03814 *dest_used = FALSE;
03815
03816 bt = ffeinfo_basictype (ffebld_info (expr));
03817 kt = ffeinfo_kindtype (ffebld_info (expr));
03818 tree_type = ffecom_tree_type[bt][kt];
03819
03820 if (list != NULL)
03821 {
03822 arg1 = ffebld_head (list);
03823 if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY)
03824 return error_mark_node;
03825 if ((list = ffebld_trail (list)) != NULL)
03826 {
03827 arg2 = ffebld_head (list);
03828 if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY)
03829 return error_mark_node;
03830 if ((list = ffebld_trail (list)) != NULL)
03831 {
03832 arg3 = ffebld_head (list);
03833 if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY)
03834 return error_mark_node;
03835 }
03836 else
03837 arg3 = NULL;
03838 }
03839 else
03840 arg2 = arg3 = NULL;
03841 }
03842 else
03843 arg1 = arg2 = arg3 = NULL;
03844
03845
03846
03847
03848 if (arg1 != NULL)
03849 arg1_type = ffecom_tree_type
03850 [ffeinfo_basictype (ffebld_info (arg1))]
03851 [ffeinfo_kindtype (ffebld_info (arg1))];
03852 else
03853 arg1_type = NULL_TREE;
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884 codegen_imp = ffebld_symter_implementation (ffebld_left (expr));
03885 gfrt = ffeintrin_gfrt_direct (codegen_imp);
03886 if (gfrt == FFECOM_gfrt)
03887 gfrt = ffeintrin_gfrt_indirect (codegen_imp);
03888
03889 switch (codegen_imp)
03890 {
03891 case FFEINTRIN_impABS:
03892 case FFEINTRIN_impCABS:
03893 case FFEINTRIN_impCDABS:
03894 case FFEINTRIN_impDABS:
03895 case FFEINTRIN_impIABS:
03896 if (ffeinfo_basictype (ffebld_info (arg1))
03897 == FFEINFO_basictypeCOMPLEX)
03898 {
03899 if (kt == FFEINFO_kindtypeREAL1)
03900 gfrt = FFECOM_gfrtCABS;
03901 else if (kt == FFEINFO_kindtypeREAL2)
03902 gfrt = FFECOM_gfrtCDABS;
03903 break;
03904 }
03905 return ffecom_1 (ABS_EXPR, tree_type,
03906 convert (tree_type, ffecom_expr (arg1)));
03907
03908 case FFEINTRIN_impACOS:
03909 case FFEINTRIN_impDACOS:
03910 break;
03911
03912 case FFEINTRIN_impAIMAG:
03913 case FFEINTRIN_impDIMAG:
03914 case FFEINTRIN_impIMAGPART:
03915 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
03916 arg1_type = TREE_TYPE (arg1_type);
03917 else
03918 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
03919
03920 return
03921 convert (tree_type,
03922 ffecom_1 (IMAGPART_EXPR, arg1_type,
03923 ffecom_expr (arg1)));
03924
03925 case FFEINTRIN_impAINT:
03926 case FFEINTRIN_impDINT:
03927 #if 0
03928
03929 return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1));
03930 #else
03931
03932 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
03933 return
03934 convert (tree_type,
03935 ffecom_3 (COND_EXPR, double_type_node,
03936 ffecom_truth_value
03937 (ffecom_2 (GE_EXPR, integer_type_node,
03938 saved_expr1,
03939 convert (arg1_type,
03940 ffecom_float_zero_))),
03941 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
03942 build_tree_list (NULL_TREE,
03943 convert (double_type_node,
03944 saved_expr1)),
03945 NULL_TREE),
03946 ffecom_1 (NEGATE_EXPR, double_type_node,
03947 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
03948 build_tree_list (NULL_TREE,
03949 convert (double_type_node,
03950 ffecom_1 (NEGATE_EXPR,
03951 arg1_type,
03952 saved_expr1))),
03953 NULL_TREE)
03954 ))
03955 );
03956 #endif
03957
03958 case FFEINTRIN_impANINT:
03959 case FFEINTRIN_impDNINT:
03960 #if 0
03961
03962 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
03963 expr_tree = convert (tree_type,
03964 convert (integer_type_node,
03965 ffecom_3 (COND_EXPR, tree_type,
03966 ffecom_truth_value
03967 (ffecom_2 (GE_EXPR,
03968 integer_type_node,
03969 saved_expr1,
03970 ffecom_float_zero_)),
03971 ffecom_2 (PLUS_EXPR,
03972 tree_type,
03973 saved_expr1,
03974 ffecom_float_half_),
03975 ffecom_2 (MINUS_EXPR,
03976 tree_type,
03977 saved_expr1,
03978 ffecom_float_half_))));
03979 return expr_tree;
03980 #else
03981
03982 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
03983 return
03984 convert (tree_type,
03985 ffecom_3 (COND_EXPR, double_type_node,
03986 ffecom_truth_value
03987 (ffecom_2 (GE_EXPR, integer_type_node,
03988 saved_expr1,
03989 convert (arg1_type,
03990 ffecom_float_zero_))),
03991 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
03992 build_tree_list (NULL_TREE,
03993 convert (double_type_node,
03994 ffecom_2 (PLUS_EXPR,
03995 arg1_type,
03996 saved_expr1,
03997 convert (arg1_type,
03998 ffecom_float_half_)))),
03999 NULL_TREE),
04000 ffecom_1 (NEGATE_EXPR, double_type_node,
04001 ffecom_call_gfrt (FFECOM_gfrtL_FLOOR,
04002 build_tree_list (NULL_TREE,
04003 convert (double_type_node,
04004 ffecom_2 (MINUS_EXPR,
04005 arg1_type,
04006 convert (arg1_type,
04007 ffecom_float_half_),
04008 saved_expr1))),
04009 NULL_TREE))
04010 )
04011 );
04012 #endif
04013
04014 case FFEINTRIN_impASIN:
04015 case FFEINTRIN_impDASIN:
04016 case FFEINTRIN_impATAN:
04017 case FFEINTRIN_impDATAN:
04018 case FFEINTRIN_impATAN2:
04019 case FFEINTRIN_impDATAN2:
04020 break;
04021
04022 case FFEINTRIN_impCHAR:
04023 case FFEINTRIN_impACHAR:
04024 #ifdef HOHO
04025 tempvar = ffecom_make_tempvar (char_type_node, 1, -1);
04026 #else
04027 tempvar = ffebld_nonter_hook (expr);
04028 assert (tempvar);
04029 #endif
04030 {
04031 tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar)));
04032
04033 expr_tree = ffecom_modify (tmv,
04034 ffecom_2 (ARRAY_REF, tmv, tempvar,
04035 integer_one_node),
04036 convert (tmv, ffecom_expr (arg1)));
04037 }
04038 expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar),
04039 expr_tree,
04040 tempvar);
04041 expr_tree = ffecom_1 (ADDR_EXPR,
04042 build_pointer_type (TREE_TYPE (expr_tree)),
04043 expr_tree);
04044 return expr_tree;
04045
04046 case FFEINTRIN_impCMPLX:
04047 case FFEINTRIN_impDCMPLX:
04048 if (arg2 == NULL)
04049 return
04050 convert (tree_type, ffecom_expr (arg1));
04051
04052 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
04053 return
04054 ffecom_2 (COMPLEX_EXPR, tree_type,
04055 convert (real_type, ffecom_expr (arg1)),
04056 convert (real_type,
04057 ffecom_expr (arg2)));
04058
04059 case FFEINTRIN_impCOMPLEX:
04060 return
04061 ffecom_2 (COMPLEX_EXPR, tree_type,
04062 ffecom_expr (arg1),
04063 ffecom_expr (arg2));
04064
04065 case FFEINTRIN_impCONJG:
04066 case FFEINTRIN_impDCONJG:
04067 {
04068 tree arg1_tree;
04069
04070 real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
04071 arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
04072 return
04073 ffecom_2 (COMPLEX_EXPR, tree_type,
04074 ffecom_1 (REALPART_EXPR, real_type, arg1_tree),
04075 ffecom_1 (NEGATE_EXPR, real_type,
04076 ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree)));
04077 }
04078
04079 case FFEINTRIN_impCOS:
04080 case FFEINTRIN_impCCOS:
04081 case FFEINTRIN_impCDCOS:
04082 case FFEINTRIN_impDCOS:
04083 if (bt == FFEINFO_basictypeCOMPLEX)
04084 {
04085 if (kt == FFEINFO_kindtypeREAL1)
04086 gfrt = FFECOM_gfrtCCOS;
04087 else if (kt == FFEINFO_kindtypeREAL2)
04088 gfrt = FFECOM_gfrtCDCOS;
04089 }
04090 break;
04091
04092 case FFEINTRIN_impCOSH:
04093 case FFEINTRIN_impDCOSH:
04094 break;
04095
04096 case FFEINTRIN_impDBLE:
04097 case FFEINTRIN_impDFLOAT:
04098 case FFEINTRIN_impDREAL:
04099 case FFEINTRIN_impFLOAT:
04100 case FFEINTRIN_impIDINT:
04101 case FFEINTRIN_impIFIX:
04102 case FFEINTRIN_impINT2:
04103 case FFEINTRIN_impINT8:
04104 case FFEINTRIN_impINT:
04105 case FFEINTRIN_impLONG:
04106 case FFEINTRIN_impREAL:
04107 case FFEINTRIN_impSHORT:
04108 case FFEINTRIN_impSNGL:
04109 return convert (tree_type, ffecom_expr (arg1));
04110
04111 case FFEINTRIN_impDIM:
04112 case FFEINTRIN_impDDIM:
04113 case FFEINTRIN_impIDIM:
04114 saved_expr1 = ffecom_save_tree (convert (tree_type,
04115 ffecom_expr (arg1)));
04116 saved_expr2 = ffecom_save_tree (convert (tree_type,
04117 ffecom_expr (arg2)));
04118 return
04119 ffecom_3 (COND_EXPR, tree_type,
04120 ffecom_truth_value
04121 (ffecom_2 (GT_EXPR, integer_type_node,
04122 saved_expr1,
04123 saved_expr2)),
04124 ffecom_2 (MINUS_EXPR, tree_type,
04125 saved_expr1,
04126 saved_expr2),
04127 convert (tree_type, ffecom_float_zero_));
04128
04129 case FFEINTRIN_impDPROD:
04130 return
04131 ffecom_2 (MULT_EXPR, tree_type,
04132 convert (tree_type, ffecom_expr (arg1)),
04133 convert (tree_type, ffecom_expr (arg2)));
04134
04135 case FFEINTRIN_impEXP:
04136 case FFEINTRIN_impCDEXP:
04137 case FFEINTRIN_impCEXP:
04138 case FFEINTRIN_impDEXP:
04139 if (bt == FFEINFO_basictypeCOMPLEX)
04140 {
04141 if (kt == FFEINFO_kindtypeREAL1)
04142 gfrt = FFECOM_gfrtCEXP;
04143 else if (kt == FFEINFO_kindtypeREAL2)
04144 gfrt = FFECOM_gfrtCDEXP;
04145 }
04146 break;
04147
04148 case FFEINTRIN_impICHAR:
04149 case FFEINTRIN_impIACHAR:
04150 #if 0
04151 ffecom_char_args_ (&expr_tree, &saved_expr1 , arg1);
04152 expr_tree
04153 = ffecom_1 (INDIRECT_REF,
04154 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
04155 expr_tree);
04156 expr_tree
04157 = ffecom_2 (ARRAY_REF,
04158 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
04159 expr_tree,
04160 integer_one_node);
04161 return convert (tree_type, expr_tree);
04162 #else
04163 expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1);
04164 expr_tree = ffecom_3 (COND_EXPR, tree_type,
04165 saved_expr1,
04166 expr_tree,
04167 convert (tree_type, integer_zero_node));
04168 return expr_tree;
04169 #endif
04170
04171 case FFEINTRIN_impINDEX:
04172 break;
04173
04174 case FFEINTRIN_impLEN:
04175 #if 0
04176 break;
04177 #else
04178 return ffecom_intrinsic_len_ (arg1);
04179 #endif
04180
04181 case FFEINTRIN_impLGE:
04182 case FFEINTRIN_impLGT:
04183 case FFEINTRIN_impLLE:
04184 case FFEINTRIN_impLLT:
04185 break;
04186
04187 case FFEINTRIN_impLOG:
04188 case FFEINTRIN_impALOG:
04189 case FFEINTRIN_impCDLOG:
04190 case FFEINTRIN_impCLOG:
04191 case FFEINTRIN_impDLOG:
04192 if (bt == FFEINFO_basictypeCOMPLEX)
04193 {
04194 if (kt == FFEINFO_kindtypeREAL1)
04195 gfrt = FFECOM_gfrtCLOG;
04196 else if (kt == FFEINFO_kindtypeREAL2)
04197 gfrt = FFECOM_gfrtCDLOG;
04198 }
04199 break;
04200
04201 case FFEINTRIN_impLOG10:
04202 case FFEINTRIN_impALOG10:
04203 case FFEINTRIN_impDLOG10:
04204 if (gfrt != FFECOM_gfrt)
04205 break;
04206
04207 if (kt == FFEINFO_kindtypeREAL1)
04208
04209 gfrt = FFECOM_gfrtL_LOG10;
04210 else if (kt == FFEINFO_kindtypeREAL2)
04211
04212 gfrt = FFECOM_gfrtL_LOG10;
04213 break;
04214
04215 case FFEINTRIN_impMAX:
04216 case FFEINTRIN_impAMAX0:
04217 case FFEINTRIN_impAMAX1:
04218 case FFEINTRIN_impDMAX1:
04219 case FFEINTRIN_impMAX0:
04220 case FFEINTRIN_impMAX1:
04221 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
04222 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
04223 else
04224 arg1_type = tree_type;
04225 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
04226 convert (arg1_type, ffecom_expr (arg1)),
04227 convert (arg1_type, ffecom_expr (arg2)));
04228 for (; list != NULL; list = ffebld_trail (list))
04229 {
04230 if ((ffebld_head (list) == NULL)
04231 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
04232 continue;
04233 expr_tree = ffecom_2 (MAX_EXPR, arg1_type,
04234 expr_tree,
04235 convert (arg1_type,
04236 ffecom_expr (ffebld_head (list))));
04237 }
04238 return convert (tree_type, expr_tree);
04239
04240 case FFEINTRIN_impMIN:
04241 case FFEINTRIN_impAMIN0:
04242 case FFEINTRIN_impAMIN1:
04243 case FFEINTRIN_impDMIN1:
04244 case FFEINTRIN_impMIN0:
04245 case FFEINTRIN_impMIN1:
04246 if (bt != ffeinfo_basictype (ffebld_info (arg1)))
04247 arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr));
04248 else
04249 arg1_type = tree_type;
04250 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
04251 convert (arg1_type, ffecom_expr (arg1)),
04252 convert (arg1_type, ffecom_expr (arg2)));
04253 for (; list != NULL; list = ffebld_trail (list))
04254 {
04255 if ((ffebld_head (list) == NULL)
04256 || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY))
04257 continue;
04258 expr_tree = ffecom_2 (MIN_EXPR, arg1_type,
04259 expr_tree,
04260 convert (arg1_type,
04261 ffecom_expr (ffebld_head (list))));
04262 }
04263 return convert (tree_type, expr_tree);
04264
04265 case FFEINTRIN_impMOD:
04266 case FFEINTRIN_impAMOD:
04267 case FFEINTRIN_impDMOD:
04268 if (bt != FFEINFO_basictypeREAL)
04269 return ffecom_2 (TRUNC_MOD_EXPR, tree_type,
04270 convert (tree_type, ffecom_expr (arg1)),
04271 convert (tree_type, ffecom_expr (arg2)));
04272
04273 if (kt == FFEINFO_kindtypeREAL1)
04274
04275 gfrt = FFECOM_gfrtL_FMOD;
04276 else if (kt == FFEINFO_kindtypeREAL2)
04277
04278 gfrt = FFECOM_gfrtL_FMOD;
04279 break;
04280
04281 case FFEINTRIN_impNINT:
04282 case FFEINTRIN_impIDNINT:
04283 #if 0
04284
04285 return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1));
04286 #else
04287
04288 saved_expr1 = ffecom_save_tree (ffecom_expr (arg1));
04289 return
04290 convert (ffecom_integer_type_node,
04291 ffecom_3 (COND_EXPR, arg1_type,
04292 ffecom_truth_value
04293 (ffecom_2 (GE_EXPR, integer_type_node,
04294 saved_expr1,
04295 convert (arg1_type,
04296 ffecom_float_zero_))),
04297 ffecom_2 (PLUS_EXPR, arg1_type,
04298 saved_expr1,
04299 convert (arg1_type,
04300 ffecom_float_half_)),
04301 ffecom_2 (MINUS_EXPR, arg1_type,
04302 saved_expr1,
04303 convert (arg1_type,
04304 ffecom_float_half_))));
04305 #endif
04306
04307 case FFEINTRIN_impSIGN:
04308 case FFEINTRIN_impDSIGN:
04309 case FFEINTRIN_impISIGN:
04310 {
04311 tree arg2_tree = ffecom_expr (arg2);
04312
04313 saved_expr1
04314 = ffecom_save_tree
04315 (ffecom_1 (ABS_EXPR, tree_type,
04316 convert (tree_type,
04317 ffecom_expr (arg1))));
04318 expr_tree
04319 = ffecom_3 (COND_EXPR, tree_type,
04320 ffecom_truth_value
04321 (ffecom_2 (GE_EXPR, integer_type_node,
04322 arg2_tree,
04323 convert (TREE_TYPE (arg2_tree),
04324 integer_zero_node))),
04325 saved_expr1,
04326 ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1));
04327
04328 expr_tree
04329 = ffecom_2 (COMPOUND_EXPR, tree_type,
04330 convert (void_type_node, saved_expr1),
04331 expr_tree);
04332 }
04333 return expr_tree;
04334
04335 case FFEINTRIN_impSIN:
04336 case FFEINTRIN_impCDSIN:
04337 case FFEINTRIN_impCSIN:
04338 case FFEINTRIN_impDSIN:
04339 if (bt == FFEINFO_basictypeCOMPLEX)
04340 {
04341 if (kt == FFEINFO_kindtypeREAL1)
04342 gfrt = FFECOM_gfrtCSIN;
04343 else if (kt == FFEINFO_kindtypeREAL2)
04344 gfrt = FFECOM_gfrtCDSIN;
04345 }
04346 break;
04347
04348 case FFEINTRIN_impSINH:
04349 case FFEINTRIN_impDSINH:
04350 break;
04351
04352 case FFEINTRIN_impSQRT:
04353 case FFEINTRIN_impCDSQRT:
04354 case FFEINTRIN_impCSQRT:
04355 case FFEINTRIN_impDSQRT:
04356 if (bt == FFEINFO_basictypeCOMPLEX)
04357 {
04358 if (kt == FFEINFO_kindtypeREAL1)
04359 gfrt = FFECOM_gfrtCSQRT;
04360 else if (kt == FFEINFO_kindtypeREAL2)
04361 gfrt = FFECOM_gfrtCDSQRT;
04362 }
04363 break;
04364
04365 case FFEINTRIN_impTAN:
04366 case FFEINTRIN_impDTAN:
04367 case FFEINTRIN_impTANH:
04368 case FFEINTRIN_impDTANH:
04369 break;
04370
04371 case FFEINTRIN_impREALPART:
04372 if (TREE_CODE (arg1_type) == COMPLEX_TYPE)
04373 arg1_type = TREE_TYPE (arg1_type);
04374 else
04375 arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type));
04376
04377 return
04378 convert (tree_type,
04379 ffecom_1 (REALPART_EXPR, arg1_type,
04380 ffecom_expr (arg1)));
04381
04382 case FFEINTRIN_impIAND:
04383 case FFEINTRIN_impAND:
04384 return ffecom_2 (BIT_AND_EXPR, tree_type,
04385 convert (tree_type,
04386 ffecom_expr (arg1)),
04387 convert (tree_type,
04388 ffecom_expr (arg2)));
04389
04390 case FFEINTRIN_impIOR:
04391 case FFEINTRIN_impOR:
04392 return ffecom_2 (BIT_IOR_EXPR, tree_type,
04393 convert (tree_type,
04394 ffecom_expr (arg1)),
04395 convert (tree_type,
04396 ffecom_expr (arg2)));
04397
04398 case FFEINTRIN_impIEOR:
04399 case FFEINTRIN_impXOR:
04400 return ffecom_2 (BIT_XOR_EXPR, tree_type,
04401 convert (tree_type,
04402 ffecom_expr (arg1)),
04403 convert (tree_type,
04404 ffecom_expr (arg2)));
04405
04406 case FFEINTRIN_impLSHIFT:
04407 return ffecom_2 (LSHIFT_EXPR, tree_type,
04408 ffecom_expr (arg1),
04409 convert (integer_type_node,
04410 ffecom_expr (arg2)));
04411
04412 case FFEINTRIN_impRSHIFT:
04413 return ffecom_2 (RSHIFT_EXPR, tree_type,
04414 ffecom_expr (arg1),
04415 convert (integer_type_node,
04416 ffecom_expr (arg2)));
04417
04418 case FFEINTRIN_impNOT:
04419 return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1));
04420
04421 case FFEINTRIN_impBIT_SIZE:
04422 return convert (tree_type, TYPE_SIZE (arg1_type));
04423
04424 case FFEINTRIN_impBTEST:
04425 {
04426 ffetargetLogical1 target_true;
04427 ffetargetLogical1 target_false;
04428 tree true_tree;
04429 tree false_tree;
04430
04431 ffetarget_logical1 (&target_true, TRUE);
04432 ffetarget_logical1 (&target_false, FALSE);
04433 if (target_true == 1)
04434 true_tree = convert (tree_type, integer_one_node);
04435 else
04436 true_tree = convert (tree_type, build_int_2 (target_true, 0));
04437 if (target_false == 0)
04438 false_tree = convert (tree_type, integer_zero_node);
04439 else
04440 false_tree = convert (tree_type, build_int_2 (target_false, 0));
04441
04442 return
04443 ffecom_3 (COND_EXPR, tree_type,
04444 ffecom_truth_value
04445 (ffecom_2 (EQ_EXPR, integer_type_node,
04446 ffecom_2 (BIT_AND_EXPR, arg1_type,
04447 ffecom_expr (arg1),
04448 ffecom_2 (LSHIFT_EXPR, arg1_type,
04449 convert (arg1_type,
04450 integer_one_node),
04451 convert (integer_type_node,
04452 ffecom_expr (arg2)))),
04453 convert (arg1_type,
04454 integer_zero_node))),
04455 false_tree,
04456 true_tree);
04457 }
04458
04459 case FFEINTRIN_impIBCLR:
04460 return
04461 ffecom_2 (BIT_AND_EXPR, tree_type,
04462 ffecom_expr (arg1),
04463 ffecom_1 (BIT_NOT_EXPR, tree_type,
04464 ffecom_2 (LSHIFT_EXPR, tree_type,
04465 convert (tree_type,
04466 integer_one_node),
04467 convert (integer_type_node,
04468 ffecom_expr (arg2)))));
04469
04470 case FFEINTRIN_impIBITS:
04471 {
04472 tree arg3_tree = ffecom_save_tree (convert (integer_type_node,
04473 ffecom_expr (arg3)));
04474 tree uns_type
04475 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
04476
04477 expr_tree
04478 = ffecom_2 (BIT_AND_EXPR, tree_type,
04479 ffecom_2 (RSHIFT_EXPR, tree_type,
04480 ffecom_expr (arg1),
04481 convert (integer_type_node,
04482 ffecom_expr (arg2))),
04483 convert (tree_type,
04484 ffecom_2 (RSHIFT_EXPR, uns_type,
04485 ffecom_1 (BIT_NOT_EXPR,
04486 uns_type,
04487 convert (uns_type,
04488 integer_zero_node)),
04489 ffecom_2 (MINUS_EXPR,
04490 integer_type_node,
04491 TYPE_SIZE (uns_type),
04492 arg3_tree))));
04493
04494 expr_tree
04495 = ffecom_3 (COND_EXPR, tree_type,
04496 ffecom_truth_value
04497 (ffecom_2 (NE_EXPR, integer_type_node,
04498 arg3_tree,
04499 integer_zero_node)),
04500 expr_tree,
04501 convert (tree_type, integer_zero_node));
04502 }
04503 return expr_tree;
04504
04505 case FFEINTRIN_impIBSET:
04506 return
04507 ffecom_2 (BIT_IOR_EXPR, tree_type,
04508 ffecom_expr (arg1),
04509 ffecom_2 (LSHIFT_EXPR, tree_type,
04510 convert (tree_type, integer_one_node),
04511 convert (integer_type_node,
04512 ffecom_expr (arg2))));
04513
04514 case FFEINTRIN_impISHFT:
04515 {
04516 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
04517 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
04518 ffecom_expr (arg2)));
04519 tree uns_type
04520 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
04521
04522 expr_tree
04523 = ffecom_3 (COND_EXPR, tree_type,
04524 ffecom_truth_value
04525 (ffecom_2 (GE_EXPR, integer_type_node,
04526 arg2_tree,
04527 integer_zero_node)),
04528 ffecom_2 (LSHIFT_EXPR, tree_type,
04529 arg1_tree,
04530 arg2_tree),
04531 convert (tree_type,
04532 ffecom_2 (RSHIFT_EXPR, uns_type,
04533 convert (uns_type, arg1_tree),
04534 ffecom_1 (NEGATE_EXPR,
04535 integer_type_node,
04536 arg2_tree))));
04537
04538 expr_tree
04539 = ffecom_3 (COND_EXPR, tree_type,
04540 ffecom_truth_value
04541 (ffecom_2 (NE_EXPR, integer_type_node,
04542 ffecom_1 (ABS_EXPR,
04543 integer_type_node,
04544 arg2_tree),
04545 TYPE_SIZE (uns_type))),
04546 expr_tree,
04547 convert (tree_type, integer_zero_node));
04548
04549 expr_tree
04550 = ffecom_2 (COMPOUND_EXPR, tree_type,
04551 convert (void_type_node, arg1_tree),
04552 ffecom_2 (COMPOUND_EXPR, tree_type,
04553 convert (void_type_node, arg2_tree),
04554 expr_tree));
04555 }
04556 return expr_tree;
04557
04558 case FFEINTRIN_impISHFTC:
04559 {
04560 tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
04561 tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
04562 ffecom_expr (arg2)));
04563 tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type)
04564 : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3)));
04565 tree shift_neg;
04566 tree shift_pos;
04567 tree mask_arg1;
04568 tree masked_arg1;
04569 tree uns_type
04570 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
04571
04572 mask_arg1
04573 = ffecom_2 (LSHIFT_EXPR, tree_type,
04574 ffecom_1 (BIT_NOT_EXPR, tree_type,
04575 convert (tree_type, integer_zero_node)),
04576 arg3_tree);
04577
04578 mask_arg1
04579 = ffecom_3 (COND_EXPR, tree_type,
04580 ffecom_truth_value
04581 (ffecom_2 (NE_EXPR, integer_type_node,
04582 arg3_tree,
04583 TYPE_SIZE (uns_type))),
04584 mask_arg1,
04585 convert (tree_type, integer_zero_node));
04586 mask_arg1 = ffecom_save_tree (mask_arg1);
04587 masked_arg1
04588 = ffecom_2 (BIT_AND_EXPR, tree_type,
04589 arg1_tree,
04590 ffecom_1 (BIT_NOT_EXPR, tree_type,
04591 mask_arg1));
04592 masked_arg1 = ffecom_save_tree (masked_arg1);
04593 shift_neg
04594 = ffecom_2 (BIT_IOR_EXPR, tree_type,
04595 convert (tree_type,
04596 ffecom_2 (RSHIFT_EXPR, uns_type,
04597 convert (uns_type, masked_arg1),
04598 ffecom_1 (NEGATE_EXPR,
04599 integer_type_node,
04600 arg2_tree))),
04601 ffecom_2 (LSHIFT_EXPR, tree_type,
04602 arg1_tree,
04603 ffecom_2 (PLUS_EXPR, integer_type_node,
04604 arg2_tree,
04605 arg3_tree)));
04606 shift_pos
04607 = ffecom_2 (BIT_IOR_EXPR, tree_type,
04608 ffecom_2 (LSHIFT_EXPR, tree_type,
04609 arg1_tree,
04610 arg2_tree),
04611 convert (tree_type,
04612 ffecom_2 (RSHIFT_EXPR, uns_type,
04613 convert (uns_type, masked_arg1),
04614 ffecom_2 (MINUS_EXPR,
04615 integer_type_node,
04616 arg3_tree,
04617 arg2_tree))));
04618 expr_tree
04619 = ffecom_3 (COND_EXPR, tree_type,
04620 ffecom_truth_value
04621 (ffecom_2 (LT_EXPR, integer_type_node,
04622 arg2_tree,
04623 integer_zero_node)),
04624 shift_neg,
04625 shift_pos);
04626 expr_tree
04627 = ffecom_2 (BIT_IOR_EXPR, tree_type,
04628 ffecom_2 (BIT_AND_EXPR, tree_type,
04629 mask_arg1,
04630 arg1_tree),
04631 ffecom_2 (BIT_AND_EXPR, tree_type,
04632 ffecom_1 (BIT_NOT_EXPR, tree_type,
04633 mask_arg1),
04634 expr_tree));
04635 expr_tree
04636 = ffecom_3 (COND_EXPR, tree_type,
04637 ffecom_truth_value
04638 (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
04639 ffecom_2 (EQ_EXPR, integer_type_node,
04640 ffecom_1 (ABS_EXPR,
04641 integer_type_node,
04642 arg2_tree),
04643 arg3_tree),
04644 ffecom_2 (EQ_EXPR, integer_type_node,
04645 arg2_tree,
04646 integer_zero_node))),
04647 arg1_tree,
04648 expr_tree);
04649
04650 expr_tree
04651 = ffecom_2 (COMPOUND_EXPR, tree_type,
04652 convert (void_type_node, arg1_tree),
04653 ffecom_2 (COMPOUND_EXPR, tree_type,
04654 convert (void_type_node, arg2_tree),
04655 ffecom_2 (COMPOUND_EXPR, tree_type,
04656 convert (void_type_node,
04657 mask_arg1),
04658 ffecom_2 (COMPOUND_EXPR, tree_type,
04659 convert (void_type_node,
04660 masked_arg1),
04661 expr_tree))));
04662 expr_tree
04663 = ffecom_2 (COMPOUND_EXPR, tree_type,
04664 convert (void_type_node,
04665 arg3_tree),
04666 expr_tree);
04667 }
04668 return expr_tree;
04669
04670 case FFEINTRIN_impLOC:
04671 {
04672 tree arg1_tree = ffecom_expr (arg1);
04673
04674 expr_tree
04675 = convert (tree_type,
04676 ffecom_1 (ADDR_EXPR,
04677 build_pointer_type (TREE_TYPE (arg1_tree)),
04678 arg1_tree));
04679 }
04680 return expr_tree;
04681
04682 case FFEINTRIN_impMVBITS:
04683 {
04684 tree arg1_tree;
04685 tree arg2_tree;
04686 tree arg3_tree;
04687 ffebld arg4 = ffebld_head (ffebld_trail (list));
04688 tree arg4_tree;
04689 tree arg4_type;
04690 ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list)));
04691 tree arg5_tree;
04692 tree prep_arg1;
04693 tree prep_arg4;
04694 tree arg5_plus_arg3;
04695
04696 arg2_tree = convert (integer_type_node,
04697 ffecom_expr (arg2));
04698 arg3_tree = ffecom_save_tree (convert (integer_type_node,
04699 ffecom_expr (arg3)));
04700 arg4_tree = ffecom_expr_rw (NULL_TREE, arg4);
04701 arg4_type = TREE_TYPE (arg4_tree);
04702
04703 arg1_tree = ffecom_save_tree (convert (arg4_type,
04704 ffecom_expr (arg1)));
04705
04706 arg5_tree = ffecom_save_tree (convert (integer_type_node,
04707 ffecom_expr (arg5)));
04708
04709 prep_arg1
04710 = ffecom_2 (LSHIFT_EXPR, arg4_type,
04711 ffecom_2 (BIT_AND_EXPR, arg4_type,
04712 ffecom_2 (RSHIFT_EXPR, arg4_type,
04713 arg1_tree,
04714 arg2_tree),
04715 ffecom_1 (BIT_NOT_EXPR, arg4_type,
04716 ffecom_2 (LSHIFT_EXPR, arg4_type,
04717 ffecom_1 (BIT_NOT_EXPR,
04718 arg4_type,
04719 convert
04720 (arg4_type,
04721 integer_zero_node)),
04722 arg3_tree))),
04723 arg5_tree);
04724 arg5_plus_arg3
04725 = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type,
04726 arg5_tree,
04727 arg3_tree));
04728 prep_arg4
04729 = ffecom_2 (LSHIFT_EXPR, arg4_type,
04730 ffecom_1 (BIT_NOT_EXPR, arg4_type,
04731 convert (arg4_type,
04732 integer_zero_node)),
04733 arg5_plus_arg3);
04734
04735 prep_arg4
04736 = ffecom_3 (COND_EXPR, arg4_type,
04737 ffecom_truth_value
04738 (ffecom_2 (NE_EXPR, integer_type_node,
04739 arg5_plus_arg3,
04740 convert (TREE_TYPE (arg5_plus_arg3),
04741 TYPE_SIZE (arg4_type)))),
04742 prep_arg4,
04743 convert (arg4_type, integer_zero_node));
04744 prep_arg4
04745 = ffecom_2 (BIT_AND_EXPR, arg4_type,
04746 arg4_tree,
04747 ffecom_2 (BIT_IOR_EXPR, arg4_type,
04748 prep_arg4,
04749 ffecom_1 (BIT_NOT_EXPR, arg4_type,
04750 ffecom_2 (LSHIFT_EXPR, arg4_type,
04751 ffecom_1 (BIT_NOT_EXPR,
04752 arg4_type,
04753 convert
04754 (arg4_type,
04755 integer_zero_node)),
04756 arg5_tree))));
04757 prep_arg1
04758 = ffecom_2 (BIT_IOR_EXPR, arg4_type,
04759 prep_arg1,
04760 prep_arg4);
04761
04762
04763 prep_arg1
04764 = ffecom_3 (COND_EXPR, arg4_type,
04765 ffecom_truth_value
04766 (ffecom_2 (NE_EXPR, integer_type_node,
04767 arg3_tree,
04768 convert (TREE_TYPE (arg3_tree),
04769 integer_zero_node))),
04770 prep_arg1,
04771 arg4_tree);
04772 prep_arg1
04773 = ffecom_3 (COND_EXPR, arg4_type,
04774 ffecom_truth_value
04775 (ffecom_2 (NE_EXPR, integer_type_node,
04776 arg3_tree,
04777 convert (TREE_TYPE (arg3_tree),
04778 TYPE_SIZE (arg4_type)))),
04779 prep_arg1,
04780 arg1_tree);
04781 expr_tree
04782 = ffecom_2s (MODIFY_EXPR, void_type_node,
04783 arg4_tree,
04784 prep_arg1);
04785
04786 expr_tree
04787 = ffecom_2 (COMPOUND_EXPR, void_type_node,
04788 arg1_tree,
04789 ffecom_2 (COMPOUND_EXPR, void_type_node,
04790 arg3_tree,
04791 ffecom_2 (COMPOUND_EXPR, void_type_node,
04792 arg5_tree,
04793 ffecom_2 (COMPOUND_EXPR, void_type_node,
04794 arg5_plus_arg3,
04795 expr_tree))));
04796 expr_tree
04797 = ffecom_2 (COMPOUND_EXPR, void_type_node,
04798 arg4_tree,
04799 expr_tree);
04800
04801 }
04802 return expr_tree;
04803
04804 case FFEINTRIN_impDERF:
04805 case FFEINTRIN_impERF:
04806 case FFEINTRIN_impDERFC:
04807 case FFEINTRIN_impERFC:
04808 break;
04809
04810 case FFEINTRIN_impIARGC:
04811
04812 expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_),
04813 ffecom_tree_xargc_,
04814 convert (TREE_TYPE (ffecom_tree_xargc_),
04815 integer_one_node));
04816 return expr_tree;
04817
04818 case FFEINTRIN_impSIGNAL_func:
04819 case FFEINTRIN_impSIGNAL_subr:
04820 {
04821 tree arg1_tree;
04822 tree arg2_tree;
04823 tree arg3_tree;
04824
04825 arg1_tree = convert (ffecom_f2c_integer_type_node,
04826 ffecom_expr (arg1));
04827 arg1_tree = ffecom_1 (ADDR_EXPR,
04828 build_pointer_type (TREE_TYPE (arg1_tree)),
04829 arg1_tree);
04830
04831
04832 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
04833 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
04834 else
04835 arg2_tree = ffecom_ptr_to_expr (arg2);
04836 arg2_tree = convert (TREE_TYPE (null_pointer_node),
04837 arg2_tree);
04838
04839 if (arg3 != NULL)
04840 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
04841 else
04842 arg3_tree = NULL_TREE;
04843
04844 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
04845 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
04846 TREE_CHAIN (arg1_tree) = arg2_tree;
04847
04848 expr_tree
04849 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
04850 ffecom_gfrt_kindtype (gfrt),
04851 FALSE,
04852 ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ?
04853 NULL_TREE :
04854 tree_type),
04855 arg1_tree,
04856 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
04857 ffebld_nonter_hook (expr));
04858
04859 if (arg3_tree != NULL_TREE)
04860 expr_tree
04861 = ffecom_modify (NULL_TREE, arg3_tree,
04862 convert (TREE_TYPE (arg3_tree),
04863 expr_tree));
04864 }
04865 return expr_tree;
04866
04867 case FFEINTRIN_impALARM:
04868 {
04869 tree arg1_tree;
04870 tree arg2_tree;
04871 tree arg3_tree;
04872
04873 arg1_tree = convert (ffecom_f2c_integer_type_node,
04874 ffecom_expr (arg1));
04875 arg1_tree = ffecom_1 (ADDR_EXPR,
04876 build_pointer_type (TREE_TYPE (arg1_tree)),
04877 arg1_tree);
04878
04879
04880 if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY)
04881 arg2_tree = convert (integer_type_node, ffecom_expr (arg2));
04882 else
04883 arg2_tree = ffecom_ptr_to_expr (arg2);
04884 arg2_tree = convert (TREE_TYPE (null_pointer_node),
04885 arg2_tree);
04886
04887 if (arg3 != NULL)
04888 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
04889 else
04890 arg3_tree = NULL_TREE;
04891
04892 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
04893 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
04894 TREE_CHAIN (arg1_tree) = arg2_tree;
04895
04896 expr_tree
04897 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
04898 ffecom_gfrt_kindtype (gfrt),
04899 FALSE,
04900 NULL_TREE,
04901 arg1_tree,
04902 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
04903 ffebld_nonter_hook (expr));
04904
04905 if (arg3_tree != NULL_TREE)
04906 expr_tree
04907 = ffecom_modify (NULL_TREE, arg3_tree,
04908 convert (TREE_TYPE (arg3_tree),
04909 expr_tree));
04910 }
04911 return expr_tree;
04912
04913 case FFEINTRIN_impCHDIR_subr:
04914 case FFEINTRIN_impFDATE_subr:
04915 case FFEINTRIN_impFGET_subr:
04916 case FFEINTRIN_impFPUT_subr:
04917 case FFEINTRIN_impGETCWD_subr:
04918 case FFEINTRIN_impHOSTNM_subr:
04919 case FFEINTRIN_impSYSTEM_subr:
04920 case FFEINTRIN_impUNLINK_subr:
04921 {
04922 tree arg1_len = integer_zero_node;
04923 tree arg1_tree;
04924 tree arg2_tree;
04925
04926 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
04927
04928 if (arg2 != NULL)
04929 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
04930 else
04931 arg2_tree = NULL_TREE;
04932
04933 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
04934 arg1_len = build_tree_list (NULL_TREE, arg1_len);
04935 TREE_CHAIN (arg1_tree) = arg1_len;
04936
04937 expr_tree
04938 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
04939 ffecom_gfrt_kindtype (gfrt),
04940 FALSE,
04941 NULL_TREE,
04942 arg1_tree,
04943 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
04944 ffebld_nonter_hook (expr));
04945
04946 if (arg2_tree != NULL_TREE)
04947 expr_tree
04948 = ffecom_modify (NULL_TREE, arg2_tree,
04949 convert (TREE_TYPE (arg2_tree),
04950 expr_tree));
04951 }
04952 return expr_tree;
04953
04954 case FFEINTRIN_impEXIT:
04955 if (arg1 != NULL)
04956 break;
04957
04958 expr_tree = build_tree_list (NULL_TREE,
04959 ffecom_1 (ADDR_EXPR,
04960 build_pointer_type
04961 (ffecom_integer_type_node),
04962 integer_zero_node));
04963
04964 return
04965 ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
04966 ffecom_gfrt_kindtype (gfrt),
04967 FALSE,
04968 void_type_node,
04969 expr_tree,
04970 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
04971 ffebld_nonter_hook (expr));
04972
04973 case FFEINTRIN_impFLUSH:
04974 if (arg1 == NULL)
04975 gfrt = FFECOM_gfrtFLUSH;
04976 else
04977 gfrt = FFECOM_gfrtFLUSH1;
04978 break;
04979
04980 case FFEINTRIN_impCHMOD_subr:
04981 case FFEINTRIN_impLINK_subr:
04982 case FFEINTRIN_impRENAME_subr:
04983 case FFEINTRIN_impSYMLNK_subr:
04984 {
04985 tree arg1_len = integer_zero_node;
04986 tree arg1_tree;
04987 tree arg2_len = integer_zero_node;
04988 tree arg2_tree;
04989 tree arg3_tree;
04990
04991 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
04992 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
04993 if (arg3 != NULL)
04994 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
04995 else
04996 arg3_tree = NULL_TREE;
04997
04998 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
04999 arg1_len = build_tree_list (NULL_TREE, arg1_len);
05000 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
05001 arg2_len = build_tree_list (NULL_TREE, arg2_len);
05002 TREE_CHAIN (arg1_tree) = arg2_tree;
05003 TREE_CHAIN (arg2_tree) = arg1_len;
05004 TREE_CHAIN (arg1_len) = arg2_len;
05005 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
05006 ffecom_gfrt_kindtype (gfrt),
05007 FALSE,
05008 NULL_TREE,
05009 arg1_tree,
05010 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
05011 ffebld_nonter_hook (expr));
05012 if (arg3_tree != NULL_TREE)
05013 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
05014 convert (TREE_TYPE (arg3_tree),
05015 expr_tree));
05016 }
05017 return expr_tree;
05018
05019 case FFEINTRIN_impLSTAT_subr:
05020 case FFEINTRIN_impSTAT_subr:
05021 {
05022 tree arg1_len = integer_zero_node;
05023 tree arg1_tree;
05024 tree arg2_tree;
05025 tree arg3_tree;
05026
05027 arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len);
05028
05029 arg2_tree = ffecom_ptr_to_expr (arg2);
05030
05031 if (arg3 != NULL)
05032 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
05033 else
05034 arg3_tree = NULL_TREE;
05035
05036 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
05037 arg1_len = build_tree_list (NULL_TREE, arg1_len);
05038 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
05039 TREE_CHAIN (arg1_tree) = arg2_tree;
05040 TREE_CHAIN (arg2_tree) = arg1_len;
05041 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
05042 ffecom_gfrt_kindtype (gfrt),
05043 FALSE,
05044 NULL_TREE,
05045 arg1_tree,
05046 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
05047 ffebld_nonter_hook (expr));
05048 if (arg3_tree != NULL_TREE)
05049 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
05050 convert (TREE_TYPE (arg3_tree),
05051 expr_tree));
05052 }
05053 return expr_tree;
05054
05055 case FFEINTRIN_impFGETC_subr:
05056 case FFEINTRIN_impFPUTC_subr:
05057 {
05058 tree arg1_tree;
05059 tree arg2_tree;
05060 tree arg2_len = integer_zero_node;
05061 tree arg3_tree;
05062
05063 arg1_tree = convert (ffecom_f2c_integer_type_node,
05064 ffecom_expr (arg1));
05065 arg1_tree = ffecom_1 (ADDR_EXPR,
05066 build_pointer_type (TREE_TYPE (arg1_tree)),
05067 arg1_tree);
05068
05069 arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len);
05070 if (arg3 != NULL)
05071 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
05072 else
05073 arg3_tree = NULL_TREE;
05074
05075 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
05076 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
05077 arg2_len = build_tree_list (NULL_TREE, arg2_len);
05078 TREE_CHAIN (arg1_tree) = arg2_tree;
05079 TREE_CHAIN (arg2_tree) = arg2_len;
05080
05081 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
05082 ffecom_gfrt_kindtype (gfrt),
05083 FALSE,
05084 NULL_TREE,
05085 arg1_tree,
05086 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
05087 ffebld_nonter_hook (expr));
05088 if (arg3_tree != NULL_TREE)
05089 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
05090 convert (TREE_TYPE (arg3_tree),
05091 expr_tree));
05092 }
05093 return expr_tree;
05094
05095 case FFEINTRIN_impFSTAT_subr:
05096 {
05097 tree arg1_tree;
05098 tree arg2_tree;
05099 tree arg3_tree;
05100
05101 arg1_tree = convert (ffecom_f2c_integer_type_node,
05102 ffecom_expr (arg1));
05103 arg1_tree = ffecom_1 (ADDR_EXPR,
05104 build_pointer_type (TREE_TYPE (arg1_tree)),
05105 arg1_tree);
05106
05107 arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node,
05108 ffecom_ptr_to_expr (arg2));
05109
05110 if (arg3 == NULL)
05111 arg3_tree = NULL_TREE;
05112 else
05113 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
05114
05115 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
05116 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
05117 TREE_CHAIN (arg1_tree) = arg2_tree;
05118 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
05119 ffecom_gfrt_kindtype (gfrt),
05120 FALSE,
05121 NULL_TREE,
05122 arg1_tree,
05123 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
05124 ffebld_nonter_hook (expr));
05125 if (arg3_tree != NULL_TREE) {
05126 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
05127 convert (TREE_TYPE (arg3_tree),
05128 expr_tree));
05129 }
05130 }
05131 return expr_tree;
05132
05133 case FFEINTRIN_impKILL_subr:
05134 {
05135 tree arg1_tree;
05136 tree arg2_tree;
05137 tree arg3_tree;
05138
05139 arg1_tree = convert (ffecom_f2c_integer_type_node,
05140 ffecom_expr (arg1));
05141 arg1_tree = ffecom_1 (ADDR_EXPR,
05142 build_pointer_type (TREE_TYPE (arg1_tree)),
05143 arg1_tree);
05144
05145 arg2_tree = convert (ffecom_f2c_integer_type_node,
05146 ffecom_expr (arg2));
05147 arg2_tree = ffecom_1 (ADDR_EXPR,
05148 build_pointer_type (TREE_TYPE (arg2_tree)),
05149 arg2_tree);
05150
05151 if (arg3 == NULL)
05152 arg3_tree = NULL_TREE;
05153 else
05154 arg3_tree = ffecom_expr_w (NULL_TREE, arg3);
05155
05156 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
05157 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
05158 TREE_CHAIN (arg1_tree) = arg2_tree;
05159 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
05160 ffecom_gfrt_kindtype (gfrt),
05161 FALSE,
05162 NULL_TREE,
05163 arg1_tree,
05164 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
05165 ffebld_nonter_hook (expr));
05166 if (arg3_tree != NULL_TREE) {
05167 expr_tree = ffecom_modify (NULL_TREE, arg3_tree,
05168 convert (TREE_TYPE (arg3_tree),
05169 expr_tree));
05170 }
05171 }
05172 return expr_tree;
05173
05174 case FFEINTRIN_impCTIME_subr:
05175 case FFEINTRIN_impTTYNAM_subr:
05176 {
05177 tree arg1_len = integer_zero_node;
05178 tree arg1_tree;
05179 tree arg2_tree;
05180
05181 arg1_tree = ffecom_arg_ptr_to_expr (arg2, &arg1_len);
05182
05183 arg2_tree = convert (((codegen_imp == FFEINTRIN_impCTIME_subr) ?
05184 ffecom_f2c_longint_type_node :
05185 ffecom_f2c_integer_type_node),
05186 ffecom_expr (arg1));
05187 arg2_tree = ffecom_1 (ADDR_EXPR,
05188 build_pointer_type (TREE_TYPE (arg2_tree)),
05189 arg2_tree);
05190
05191 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
05192 arg1_len = build_tree_list (NULL_TREE, arg1_len);
05193 arg2_tree = build_tree_list (NULL_TREE, arg2_tree);
05194 TREE_CHAIN (arg1_len) = arg2_tree;
05195 TREE_CHAIN (arg1_tree) = arg1_len;
05196
05197 expr_tree
05198 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
05199 ffecom_gfrt_kindtype (gfrt),
05200 FALSE,
05201 NULL_TREE,
05202 arg1_tree,
05203 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
05204 ffebld_nonter_hook (expr));
05205 TREE_SIDE_EFFECTS (expr_tree) = 1;
05206 }
05207 return expr_tree;
05208
05209 case FFEINTRIN_impIRAND:
05210 case FFEINTRIN_impRAND:
05211
05212 {
05213 tree arg1_tree;
05214
05215 if (arg1 == NULL)
05216 arg1_tree = ffecom_integer_zero_node;
05217 else
05218 arg1_tree = ffecom_expr (arg1);
05219 arg1_tree = convert (ffecom_f2c_integer_type_node,
05220 arg1_tree);
05221 arg1_tree = ffecom_1 (ADDR_EXPR,
05222 build_pointer_type (TREE_TYPE (arg1_tree)),
05223 arg1_tree);
05224 arg1_tree = build_tree_list (NULL_TREE, arg1_tree);
05225
05226 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
05227 ffecom_gfrt_kindtype (gfrt),
05228 FALSE,
05229 ((codegen_imp == FFEINTRIN_impIRAND) ?
05230 ffecom_f2c_integer_type_node :
05231 ffecom_f2c_real_type_node),
05232 arg1_tree,
05233 dest_tree, dest, dest_used,
05234 NULL_TREE, TRUE,
05235 ffebld_nonter_hook (expr));
05236 }
05237 return expr_tree;
05238
05239 case FFEINTRIN_impFTELL_subr:
05240 case FFEINTRIN_impUMASK_subr:
05241 {
05242 tree arg1_tree;
05243 tree arg2_tree;
05244
05245 arg1_tree = convert (ffecom_f2c_integer_type_node,
05246 ffecom_expr (arg1));
05247 arg1_tree = ffecom_1 (ADDR_EXPR,
05248 build_pointer_type (TREE_TYPE (arg1_tree)),
05249 arg1_tree);
05250
05251 if (arg2 == NULL)
05252 arg2_tree = NULL_TREE;
05253 else
05254 arg2_tree = ffecom_expr_w (NULL_TREE, arg2);
05255
05256 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
05257 ffecom_gfrt_kindtype (gfrt),
05258 FALSE,
05259 NULL_TREE,
05260 build_tree_list (NULL_TREE, arg1_tree),
05261 NULL_TREE, NULL, NULL, NULL_TREE,
05262 TRUE,
05263 ffebld_nonter_hook (expr));
05264 if (arg2_tree != NULL_TREE) {
05265 expr_tree = ffecom_modify (NULL_TREE, arg2_tree,
05266 convert (TREE_TYPE (arg2_tree),
05267 expr_tree));
05268 }
05269 }
05270 return expr_tree;
05271
05272 case FFEINTRIN_impCPU_TIME:
05273 case FFEINTRIN_impSECOND_subr:
05274 {
05275 tree arg1_tree;
05276
05277 arg1_tree = ffecom_expr_w (NULL_TREE, arg1);
05278
05279 expr_tree
05280 = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
05281 ffecom_gfrt_kindtype (gfrt),
05282 FALSE,
05283 NULL_TREE,
05284 NULL_TREE,
05285 NULL_TREE, NULL, NULL, NULL_TREE, TRUE,
05286 ffebld_nonter_hook (expr));
05287
05288 expr_tree
05289 = ffecom_modify (NULL_TREE, arg1_tree,
05290 convert (TREE_TYPE (arg1_tree),
05291 expr_tree));
05292 }
05293 return expr_tree;
05294
05295 case FFEINTRIN_impDTIME_subr:
05296 case FFEINTRIN_impETIME_subr:
05297 {
05298 tree arg1_tree;
05299 tree result_tree;
05300
05301 result_tree = ffecom_expr_w (NULL_TREE, arg2);
05302
05303 arg1_tree = ffecom_ptr_to_expr (arg1);
05304
05305 expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt),
05306 ffecom_gfrt_kindtype (gfrt),
05307 FALSE,
05308 NULL_TREE,
05309 build_tree_list (NULL_TREE, arg1_tree),
05310 NULL_TREE, NULL, NULL, NULL_TREE,
05311 TRUE,
05312 ffebld_nonter_hook (expr));
05313 expr_tree = ffecom_modify (NULL_TREE, result_tree,
05314 convert (TREE_TYPE (result_tree),
05315 expr_tree));
05316 }
05317 return expr_tree;
05318
05319
05320 case FFEINTRIN_impABORT:
05321 case FFEINTRIN_impACCESS:
05322 case FFEINTRIN_impBESJ0:
05323 case FFEINTRIN_impBESJ1:
05324 case FFEINTRIN_impBESJN:
05325 case FFEINTRIN_impBESY0:
05326 case FFEINTRIN_impBESY1:
05327 case FFEINTRIN_impBESYN:
05328 case FFEINTRIN_impCHDIR_func:
05329 case FFEINTRIN_impCHMOD_func:
05330 case FFEINTRIN_impDATE:
05331 case FFEINTRIN_impDATE_AND_TIME:
05332 case FFEINTRIN_impDBESJ0:
05333 case FFEINTRIN_impDBESJ1:
05334 case FFEINTRIN_impDBESJN:
05335 case FFEINTRIN_impDBESY0:
05336 case FFEINTRIN_impDBESY1:
05337 case FFEINTRIN_impDBESYN:
05338 case FFEINTRIN_impDTIME_func:
05339 case FFEINTRIN_impETIME_func:
05340 case FFEINTRIN_impFGETC_func:
05341 case FFEINTRIN_impFGET_func:
05342 case FFEINTRIN_impFNUM:
05343 case FFEINTRIN_impFPUTC_func:
05344 case FFEINTRIN_impFPUT_func:
05345 case FFEINTRIN_impFSEEK:
05346 case FFEINTRIN_impFSTAT_func:
05347 case FFEINTRIN_impFTELL_func:
05348 case FFEINTRIN_impGERROR:
05349 case FFEINTRIN_impGETARG:
05350 case FFEINTRIN_impGETCWD_func:
05351 case FFEINTRIN_impGETENV:
05352 case FFEINTRIN_impGETGID:
05353 case FFEINTRIN_impGETLOG:
05354 case FFEINTRIN_impGETPID:
05355 case FFEINTRIN_impGETUID:
05356 case FFEINTRIN_impGMTIME:
05357 case FFEINTRIN_impHOSTNM_func:
05358 case FFEINTRIN_impIDATE_unix:
05359 case FFEINTRIN_impIDATE_vxt:
05360 case FFEINTRIN_impIERRNO:
05361 case FFEINTRIN_impISATTY:
05362 case FFEINTRIN_impITIME:
05363 case FFEINTRIN_impKILL_func:
05364 case FFEINTRIN_impLINK_func:
05365 case FFEINTRIN_impLNBLNK:
05366 case FFEINTRIN_impLSTAT_func:
05367 case FFEINTRIN_impLTIME:
05368 case FFEINTRIN_impMCLOCK8:
05369 case FFEINTRIN_impMCLOCK:
05370 case FFEINTRIN_impPERROR:
05371 case FFEINTRIN_impRENAME_func:
05372 case FFEINTRIN_impSECNDS:
05373 case FFEINTRIN_impSECOND_func:
05374 case FFEINTRIN_impSLEEP:
05375 case FFEINTRIN_impSRAND:
05376 case FFEINTRIN_impSTAT_func:
05377 case FFEINTRIN_impSYMLNK_func:
05378 case FFEINTRIN_impSYSTEM_CLOCK:
05379 case FFEINTRIN_impSYSTEM_func:
05380 case FFEINTRIN_impTIME8:
05381 case FFEINTRIN_impTIME_unix:
05382 case FFEINTRIN_impTIME_vxt:
05383 case FFEINTRIN_impUMASK_func:
05384 case FFEINTRIN_impUNLINK_func:
05385 break;
05386
05387 case FFEINTRIN_impCTIME_func:
05388 case FFEINTRIN_impFDATE_func:
05389 case FFEINTRIN_impTTYNAM_func:
05390 case FFEINTRIN_impNONE:
05391 case FFEINTRIN_imp:
05392 fprintf (stderr, "No %s implementation.\n",
05393 ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr))));
05394 assert ("unimplemented intrinsic" == NULL);
05395 return error_mark_node;
05396 }
05397
05398 assert (gfrt != FFECOM_gfrt);
05399
05400 expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt),
05401 ffebld_right (expr));
05402
05403 return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt),
05404 (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]),
05405 tree_type,
05406 expr_tree, dest_tree, dest, dest_used,
05407 NULL_TREE, TRUE,
05408 ffebld_nonter_hook (expr));
05409
05410
05411
05412
05413
05414 }
05415
05416
05417
05418
05419
05420 static tree
05421 ffecom_expr_power_integer_ (ffebld expr)
05422 {
05423 tree l = ffecom_expr (ffebld_left (expr));
05424 tree r = ffecom_expr (ffebld_right (expr));
05425 tree ltype = TREE_TYPE (l);
05426 tree rtype = TREE_TYPE (r);
05427 tree result = NULL_TREE;
05428
05429 if (l == error_mark_node
05430 || r == error_mark_node)
05431 return error_mark_node;
05432
05433 if (TREE_CODE (r) == INTEGER_CST)
05434 {
05435 int sgn = tree_int_cst_sgn (r);
05436
05437 if (sgn == 0)
05438 return convert (ltype, integer_one_node);
05439
05440 if ((TREE_CODE (ltype) == INTEGER_TYPE)
05441 && (sgn < 0))
05442 {
05443
05444
05445
05446
05447 result = ffecom_tree_divide_ (ltype,
05448 convert (ltype, integer_one_node),
05449 l,
05450 NULL_TREE, NULL, NULL, NULL_TREE);
05451 r = ffecom_1 (NEGATE_EXPR,
05452 rtype,
05453 r);
05454 if ((TREE_INT_CST_LOW (r) & 1) == 0)
05455 result = ffecom_1 (ABS_EXPR, rtype,
05456 result);
05457 }
05458
05459
05460
05461
05462 l = save_expr (l);
05463
05464 if (sgn < 0)
05465 {
05466 l = ffecom_tree_divide_ (ltype,
05467 convert (ltype, integer_one_node),
05468 l,
05469 NULL_TREE, NULL, NULL,
05470 ffebld_nonter_hook (expr));
05471 r = ffecom_1 (NEGATE_EXPR, rtype, r);
05472 assert (TREE_CODE (r) == INTEGER_CST);
05473
05474 if (tree_int_cst_sgn (r) < 0)
05475 {
05476 r = ffecom_1 (NEGATE_EXPR, rtype,
05477 ffecom_2 (RSHIFT_EXPR, rtype,
05478 r,
05479 integer_one_node));
05480 l = save_expr (l);
05481 l = ffecom_2 (MULT_EXPR, ltype,
05482 l,
05483 l);
05484 }
05485 }
05486
05487 for (;;)
05488 {
05489 if (TREE_INT_CST_LOW (r) & 1)
05490 {
05491 if (result == NULL_TREE)
05492 result = l;
05493 else
05494 result = ffecom_2 (MULT_EXPR, ltype,
05495 result,
05496 l);
05497 }
05498
05499 r = ffecom_2 (RSHIFT_EXPR, rtype,
05500 r,
05501 integer_one_node);
05502 if (integer_zerop (r))
05503 break;
05504 assert (TREE_CODE (r) == INTEGER_CST);
05505
05506 l = save_expr (l);
05507 l = ffecom_2 (MULT_EXPR, ltype,
05508 l,
05509 l);
05510 }
05511 return result;
05512 }
05513
05514
05515
05516
05517
05518
05519
05520
05521
05522
05523
05524
05525
05526 if (ffecom_transform_only_dummies_)
05527 return NULL_TREE;
05528
05529
05530
05531
05532
05533
05534
05535
05536
05537
05538
05539
05540
05541
05542
05543
05544
05545
05546
05547
05548
05549
05550
05551
05552
05553
05554
05555
05556
05557
05558
05559
05560
05561
05562
05563
05564
05565
05566
05567
05568
05569
05570
05571
05572
05573
05574
05575
05576
05577
05578
05579
05580
05581
05582
05583
05584
05585
05586
05587 {
05588 tree rtmp;
05589 tree ltmp;
05590 tree divide;
05591 tree basetypeof_l_is_int;
05592 tree se;
05593 tree t;
05594
05595 basetypeof_l_is_int
05596 = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0);
05597
05598 se = expand_start_stmt_expr (1);
05599
05600 ffecom_start_compstmt ();
05601
05602 #ifndef HAHA
05603 rtmp = ffecom_make_tempvar ("power_r", rtype,
05604 FFETARGET_charactersizeNONE, -1);
05605 ltmp = ffecom_make_tempvar ("power_l", ltype,
05606 FFETARGET_charactersizeNONE, -1);
05607 result = ffecom_make_tempvar ("power_res", ltype,
05608 FFETARGET_charactersizeNONE, -1);
05609 if (TREE_CODE (ltype) == COMPLEX_TYPE
05610 || TREE_CODE (ltype) == RECORD_TYPE)
05611 divide = ffecom_make_tempvar ("power_div", ltype,
05612 FFETARGET_charactersizeNONE, -1);
05613 else
05614 divide = NULL_TREE;
05615 #else
05616 {
05617 tree hook;
05618
05619 hook = ffebld_nonter_hook (expr);
05620 assert (hook);
05621 assert (TREE_CODE (hook) == TREE_VEC);
05622 assert (TREE_VEC_LENGTH (hook) == 4);
05623 rtmp = TREE_VEC_ELT (hook, 0);
05624 ltmp = TREE_VEC_ELT (hook, 1);
05625 result = TREE_VEC_ELT (hook, 2);
05626 divide = TREE_VEC_ELT (hook, 3);
05627 if (TREE_CODE (ltype) == COMPLEX_TYPE
05628 || TREE_CODE (ltype) == RECORD_TYPE)
05629 assert (divide);
05630 else
05631 assert (! divide);
05632 }
05633 #endif
05634
05635 expand_expr_stmt (ffecom_modify (void_type_node,
05636 rtmp,
05637 r));
05638 expand_expr_stmt (ffecom_modify (void_type_node,
05639 ltmp,
05640 l));
05641 expand_start_cond (ffecom_truth_value
05642 (ffecom_2 (EQ_EXPR, integer_type_node,
05643 rtmp,
05644 convert (rtype, integer_zero_node))),
05645 0);
05646 expand_expr_stmt (ffecom_modify (void_type_node,
05647 result,
05648 convert (ltype, integer_one_node)));
05649 expand_start_else ();
05650 if (! integer_zerop (basetypeof_l_is_int))
05651 {
05652 expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node,
05653 rtmp,
05654 convert (rtype,
05655 integer_zero_node)),
05656 0);
05657 expand_expr_stmt (ffecom_modify (void_type_node,
05658 result,
05659 ffecom_tree_divide_
05660 (ltype,
05661 convert (ltype, integer_one_node),
05662 ltmp,
05663 NULL_TREE, NULL, NULL,
05664 divide)));
05665 expand_start_cond (ffecom_truth_value
05666 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
05667 ffecom_2 (LT_EXPR, integer_type_node,
05668 ltmp,
05669 convert (ltype,
05670 integer_zero_node)),
05671 ffecom_2 (EQ_EXPR, integer_type_node,
05672 ffecom_2 (BIT_AND_EXPR,
05673 rtype,
05674 ffecom_1 (NEGATE_EXPR,
05675 rtype,
05676 rtmp),
05677 convert (rtype,
05678 integer_one_node)),
05679 convert (rtype,
05680 integer_zero_node)))),
05681 0);
05682 expand_expr_stmt (ffecom_modify (void_type_node,
05683 result,
05684 ffecom_1 (NEGATE_EXPR,
05685 ltype,
05686 result)));
05687 expand_end_cond ();
05688 expand_start_else ();
05689 }
05690 expand_expr_stmt (ffecom_modify (void_type_node,
05691 result,
05692 convert (ltype, integer_one_node)));
05693 expand_start_cond (ffecom_truth_value
05694 (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node,
05695 ffecom_truth_value_invert
05696 (basetypeof_l_is_int),
05697 ffecom_2 (LT_EXPR, integer_type_node,
05698 rtmp,
05699 convert (rtype,
05700 integer_zero_node)))),
05701 0);
05702 expand_expr_stmt (ffecom_modify (void_type_node,
05703 ltmp,
05704 ffecom_tree_divide_
05705 (ltype,
05706 convert (ltype, integer_one_node),
05707 ltmp,
05708 NULL_TREE, NULL, NULL,
05709 divide)));
05710 expand_expr_stmt (ffecom_modify (void_type_node,
05711 rtmp,
05712 ffecom_1 (NEGATE_EXPR, rtype,
05713 rtmp)));
05714 expand_start_cond (ffecom_truth_value
05715 (ffecom_2 (LT_EXPR, integer_type_node,
05716 rtmp,
05717 convert (rtype, integer_zero_node))),
05718 0);
05719 expand_expr_stmt (ffecom_modify (void_type_node,
05720 rtmp,
05721 ffecom_1 (NEGATE_EXPR, rtype,
05722 ffecom_2 (RSHIFT_EXPR,
05723 rtype,
05724 rtmp,
05725 integer_one_node))));
05726 expand_expr_stmt (ffecom_modify (void_type_node,
05727 ltmp,
05728 ffecom_2 (MULT_EXPR, ltype,
05729 ltmp,
05730 ltmp)));
05731 expand_end_cond ();
05732 expand_end_cond ();
05733 expand_start_loop (1);
05734 expand_start_cond (ffecom_truth_value
05735 (ffecom_2 (BIT_AND_EXPR, rtype,
05736 rtmp,
05737 convert (rtype, integer_one_node))),
05738 0);
05739 expand_expr_stmt (ffecom_modify (void_type_node,
05740 result,
05741 ffecom_2 (MULT_EXPR, ltype,
05742 result,
05743 ltmp)));
05744 expand_end_cond ();
05745 expand_exit_loop_if_false (NULL,
05746 ffecom_truth_value
05747 (ffecom_modify (rtype,
05748 rtmp,
05749 ffecom_2 (RSHIFT_EXPR,
05750 rtype,
05751 rtmp,
05752 integer_one_node))));
05753 expand_expr_stmt (ffecom_modify (void_type_node,
05754 ltmp,
05755 ffecom_2 (MULT_EXPR, ltype,
05756 ltmp,
05757 ltmp)));
05758 expand_end_loop ();
05759 expand_end_cond ();
05760 if (!integer_zerop (basetypeof_l_is_int))
05761 expand_end_cond ();
05762 expand_expr_stmt (result);
05763
05764 t = ffecom_end_compstmt ();
05765
05766 result = expand_end_stmt_expr (se);
05767
05768
05769
05770 if (TREE_CODE (t) == BLOCK)
05771 {
05772
05773 result = build (BIND_EXPR, TREE_TYPE (result),
05774 NULL_TREE, result, t);
05775
05776
05777
05778 delete_block (t);
05779 }
05780 else
05781 result = t;
05782 }
05783
05784 return result;
05785 }
05786
05787
05788
05789
05790
05791
05792
05793
05794 static void
05795 ffecom_expr_transform_ (ffebld expr)
05796 {
05797 tree t;
05798 ffesymbol s;
05799
05800 tail_recurse:
05801
05802 if (expr == NULL)
05803 return;
05804
05805 switch (ffebld_op (expr))
05806 {
05807 case FFEBLD_opSYMTER:
05808 s = ffebld_symter (expr);
05809 t = ffesymbol_hook (s).decl_tree;
05810 if ((t == NULL_TREE)
05811 && ((ffesymbol_kind (s) != FFEINFO_kindNONE)
05812 || ((ffesymbol_where (s) != FFEINFO_whereNONE)
05813 && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC))))
05814 {
05815 s = ffecom_sym_transform_ (s);
05816 t = ffesymbol_hook (s).decl_tree;
05817
05818 }
05819 break;
05820
05821 case FFEBLD_opITEM:
05822 ffecom_expr_transform_ (ffebld_head (expr));
05823 expr = ffebld_trail (expr);
05824 goto tail_recurse;
05825
05826 default:
05827 break;
05828 }
05829
05830 switch (ffebld_arity (expr))
05831 {
05832 case 2:
05833 ffecom_expr_transform_ (ffebld_left (expr));
05834 expr = ffebld_right (expr);
05835 goto tail_recurse;
05836
05837 case 1:
05838 expr = ffebld_left (expr);
05839 goto tail_recurse;
05840
05841 default:
05842 break;
05843 }
05844
05845 return;
05846 }
05847
05848
05849
05850 static void
05851 ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
05852 {
05853 switch (tcode)
05854 {
05855 case FFECOM_f2ccodeCHAR:
05856 *type = make_signed_type (CHAR_TYPE_SIZE);
05857 break;
05858
05859 case FFECOM_f2ccodeSHORT:
05860 *type = make_signed_type (SHORT_TYPE_SIZE);
05861 break;
05862
05863 case FFECOM_f2ccodeINT:
05864 *type = make_signed_type (INT_TYPE_SIZE);
05865 break;
05866
05867 case FFECOM_f2ccodeLONG:
05868 *type = make_signed_type (LONG_TYPE_SIZE);
05869 break;
05870
05871 case FFECOM_f2ccodeLONGLONG:
05872 *type = make_signed_type (LONG_LONG_TYPE_SIZE);
05873 break;
05874
05875 case FFECOM_f2ccodeCHARPTR:
05876 *type = build_pointer_type (DEFAULT_SIGNED_CHAR
05877 ? signed_char_type_node
05878 : unsigned_char_type_node);
05879 break;
05880
05881 case FFECOM_f2ccodeFLOAT:
05882 *type = make_node (REAL_TYPE);
05883 TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE;
05884 layout_type (*type);
05885 break;
05886
05887 case FFECOM_f2ccodeDOUBLE:
05888 *type = make_node (REAL_TYPE);
05889 TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE;
05890 layout_type (*type);
05891 break;
05892
05893 case FFECOM_f2ccodeLONGDOUBLE:
05894 *type = make_node (REAL_TYPE);
05895 TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE;
05896 layout_type (*type);
05897 break;
05898
05899 case FFECOM_f2ccodeTWOREALS:
05900 *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node);
05901 break;
05902
05903 case FFECOM_f2ccodeTWODOUBLEREALS:
05904 *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node);
05905 break;
05906
05907 default:
05908 assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL);
05909 *type = error_mark_node;
05910 return;
05911 }
05912
05913 pushdecl (build_decl (TYPE_DECL,
05914 ffecom_get_invented_identifier ("__g77_f2c_%s", name),
05915 *type));
05916 }
05917
05918
05919
05920
05921 static void
05922 ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
05923 int code)
05924 {
05925 int j;
05926 tree t;
05927
05928 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
05929 if ((t = ffecom_tree_type[bt][j]) != NULL_TREE
05930 && compare_tree_int (TYPE_SIZE (t), size) == 0)
05931 {
05932 assert (code != -1);
05933 ffecom_f2c_typecode_[bt][j] = code;
05934 code = -1;
05935 }
05936 }
05937
05938
05939
05940
05941
05942 static ffeglobal
05943 ffecom_finish_global_ (ffeglobal global)
05944 {
05945 tree cbtype;
05946 tree cbt;
05947 tree size;
05948
05949 if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON)
05950 return global;
05951
05952 if (ffeglobal_common_init (global))
05953 return global;
05954
05955 cbt = ffeglobal_hook (global);
05956 if ((cbt == NULL_TREE)
05957 || !ffeglobal_common_have_size (global))
05958 return global;
05959
05960 DECL_EXTERNAL (cbt) = 0;
05961
05962
05963
05964 size = build_int_2 ((ffeglobal_common_size (global)
05965 + ffeglobal_common_pad (global)) - 1,
05966 0);
05967
05968 cbtype = TREE_TYPE (cbt);
05969 TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node,
05970 integer_zero_node,
05971 size);
05972 if (!TREE_TYPE (size))
05973 TREE_TYPE (size) = TYPE_DOMAIN (cbtype);
05974 layout_type (cbtype);
05975
05976 cbt = start_decl (cbt, FALSE);
05977 assert (cbt == ffeglobal_hook (global));
05978
05979 finish_decl (cbt, NULL_TREE, FALSE);
05980
05981 return global;
05982 }
05983
05984
05985
05986 static ffesymbol
05987 ffecom_finish_symbol_transform_ (ffesymbol s)
05988 {
05989 if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK))
05990 return s;
05991
05992
05993
05994
05995
05996
05997
05998
05999
06000
06001 if (ffesymbol_hook (s).decl_tree == NULL_TREE)
06002 {
06003 if (ffesymbol_kind (s) != FFEINFO_kindNONE
06004 || (ffesymbol_where (s) != FFEINFO_whereNONE
06005 && ffesymbol_where (s) != FFEINFO_whereINTRINSIC
06006 && ffesymbol_where (s) != FFEINFO_whereDUMMY))
06007
06008
06009
06010 s = ffecom_sym_transform_ (s);
06011 }
06012
06013 if ((ffesymbol_where (s) == FFEINFO_whereCOMMON)
06014 && (ffesymbol_hook (s).decl_tree != error_mark_node))
06015 {
06016
06017
06018
06019
06020
06021
06022 ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)),
06023 ffesymbol_storage (s));
06024 }
06025
06026 return s;
06027 }
06028
06029
06030
06031
06032
06033 static tree
06034 ffecom_get_appended_identifier_ (char us, const char *name)
06035 {
06036 int i;
06037 char *newname;
06038 tree id;
06039
06040 newname = xmalloc ((i = strlen (name)) + 1
06041 + ffe_is_underscoring ()
06042 + us);
06043 memcpy (newname, name, i);
06044 newname[i] = '_';
06045 newname[i + us] = '_';
06046 newname[i + 1 + us] = '\0';
06047 id = get_identifier (newname);
06048
06049 free (newname);
06050
06051 return id;
06052 }
06053
06054
06055
06056
06057 static tree
06058 ffecom_get_external_identifier_ (ffesymbol s)
06059 {
06060 char us;
06061 const char *name = ffesymbol_text (s);
06062
06063
06064
06065 if (!ffe_is_underscoring ()
06066 || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
06067 #if FFETARGET_isENFORCED_MAIN_NAME
06068 || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
06069 #else
06070 || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
06071 #endif
06072 || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
06073 return get_identifier (name);
06074
06075 us = ffe_is_second_underscore ()
06076 ? (strchr (name, '_') != NULL)
06077 : 0;
06078
06079 return ffecom_get_appended_identifier_ (us, name);
06080 }
06081
06082
06083
06084
06085
06086
06087
06088
06089
06090
06091
06092
06093
06094
06095
06096
06097 static tree
06098 ffecom_get_identifier_ (const char *name)
06099 {
06100
06101
06102 if (!ffe_is_underscoring ()
06103 || (strchr (name, '_') == NULL))
06104 return get_identifier (name);
06105
06106 return ffecom_get_appended_identifier_ (ffe_is_second_underscore (),
06107 name);
06108 }
06109
06110
06111
06112
06113
06114
06115
06116
06117
06118
06119
06120 static tree
06121 ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
06122 {
06123 ffebld expr = ffesymbol_sfexpr (s);
06124 tree type;
06125 tree func;
06126 tree result;
06127 bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
06128 static bool recurse = FALSE;
06129 int old_lineno = lineno;
06130 const char *old_input_filename = input_filename;
06131
06132 ffecom_nested_entry_ = s;
06133
06134
06135
06136
06137
06138
06139
06140
06141
06142 input_filename = ffesymbol_where_filename (s);
06143 lineno = ffesymbol_where_filelinenum (s);
06144
06145
06146
06147
06148 ffecom_expr_transform_ (expr);
06149
06150
06151
06152
06153
06154 assert (!recurse);
06155 recurse = TRUE;
06156
06157 push_f_function_context ();
06158
06159 if (charfunc)
06160 type = void_type_node;
06161 else
06162 {
06163 type = ffecom_tree_type[bt][kt];
06164 if (type == NULL_TREE)
06165 type = integer_type_node;
06166
06167 }
06168
06169 start_function (ffecom_get_identifier_ (ffesymbol_text (s)),
06170 build_function_type (type, NULL_TREE),
06171 1,
06172 0);
06173
06174
06175
06176
06177
06178 if (charfunc)
06179 {
06180 tree type;
06181
06182 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
06183
06184 result = ffecom_get_invented_identifier ("__g77_%s", "result");
06185
06186 ffecom_char_enhance_arg_ (&type, s);
06187
06188 type = build_pointer_type (type);
06189 result = build_decl (PARM_DECL, result, type);
06190
06191 push_parm_decl (result);
06192 }
06193 else
06194 result = NULL_TREE;
06195
06196 ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE);
06197
06198 store_parm_decls (0);
06199
06200 ffecom_start_compstmt ();
06201
06202 if (expr != NULL)
06203 {
06204 if (charfunc)
06205 {
06206 ffetargetCharacterSize sz = ffesymbol_size (s);
06207 tree result_length;
06208
06209 result_length = build_int_2 (sz, 0);
06210 TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node;
06211
06212 ffecom_prepare_let_char_ (sz, expr);
06213
06214 ffecom_prepare_end ();
06215
06216 ffecom_let_char_ (result, result_length, sz, expr);
06217 expand_null_return ();
06218 }
06219 else
06220 {
06221 ffecom_prepare_expr (expr);
06222
06223 ffecom_prepare_end ();
06224
06225 expand_return (ffecom_modify (NULL_TREE,
06226 DECL_RESULT (current_function_decl),
06227 ffecom_expr (expr)));
06228 }
06229 }
06230
06231 ffecom_end_compstmt ();
06232
06233 func = current_function_decl;
06234 finish_function (1);
06235
06236 pop_f_function_context ();
06237
06238 recurse = FALSE;
06239
06240 lineno = old_lineno;
06241 input_filename = old_input_filename;
06242
06243 ffecom_nested_entry_ = NULL;
06244
06245 return func;
06246 }
06247
06248 static const char *
06249 ffecom_gfrt_args_ (ffecomGfrt ix)
06250 {
06251 return ffecom_gfrt_argstring_[ix];
06252 }
06253
06254 static tree
06255 ffecom_gfrt_tree_ (ffecomGfrt ix)
06256 {
06257 if (ffecom_gfrt_[ix] == NULL_TREE)
06258 ffecom_make_gfrt_ (ix);
06259
06260 return ffecom_1 (ADDR_EXPR,
06261 build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])),
06262 ffecom_gfrt_[ix]);
06263 }
06264
06265
06266
06267
06268
06269 #define NUM_TRACKED_CHUNK 63
06270 static struct tree_ggc_tracker
06271 {
06272 struct tree_ggc_tracker *next;
06273 tree trees[NUM_TRACKED_CHUNK];
06274 } *tracker_head = NULL;
06275
06276 static void
06277 mark_tracker_head (void *arg)
06278 {
06279 struct tree_ggc_tracker *head;
06280 int i;
06281
06282 for (head = * (struct tree_ggc_tracker **) arg;
06283 head != NULL;
06284 head = head->next)
06285 {
06286 ggc_mark (head);
06287 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
06288 ggc_mark_tree (head->trees[i]);
06289 }
06290 }
06291
06292 void
06293 ffecom_save_tree_forever (tree t)
06294 {
06295 int i;
06296 if (tracker_head != NULL)
06297 for (i = 0; i < NUM_TRACKED_CHUNK; i++)
06298 if (tracker_head->trees[i] == NULL)
06299 {
06300 tracker_head->trees[i] = t;
06301 return;
06302 }
06303
06304 {
06305
06306 struct tree_ggc_tracker *old_head = tracker_head;
06307
06308 tracker_head = ggc_alloc (sizeof (*tracker_head));
06309 tracker_head->next = old_head;
06310 tracker_head->trees[0] = t;
06311 for (i = 1; i < NUM_TRACKED_CHUNK; i++)
06312 tracker_head->trees[i] = NULL;
06313 }
06314 }
06315
06316 static tree
06317 ffecom_init_zero_ (tree decl)
06318 {
06319 tree init;
06320 int incremental = TREE_STATIC (decl);
06321 tree type = TREE_TYPE (decl);
06322
06323 if (incremental)
06324 {
06325 make_decl_rtl (decl, NULL);
06326 assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1);
06327 }
06328
06329 if ((TREE_CODE (type) != ARRAY_TYPE)
06330 && (TREE_CODE (type) != RECORD_TYPE)
06331 && (TREE_CODE (type) != UNION_TYPE)
06332 && !incremental)
06333 init = convert (type, integer_zero_node);
06334 else if (!incremental)
06335 {
06336 init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
06337 TREE_CONSTANT (init) = 1;
06338 TREE_STATIC (init) = 1;
06339 }
06340 else
06341 {
06342 assemble_zeros (int_size_in_bytes (type));
06343 init = error_mark_node;
06344 }
06345
06346 return init;
06347 }
06348
06349 static tree
06350 ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
06351 tree *maybe_tree)
06352 {
06353 tree expr_tree;
06354 tree length_tree;
06355
06356 switch (ffebld_op (arg))
06357 {
06358 case FFEBLD_opCONTER:
06359 if (ffetarget_length_character1
06360 (ffebld_constant_character1
06361 (ffebld_conter (arg))) == 0)
06362 {
06363 *maybe_tree = integer_zero_node;
06364 return convert (tree_type, integer_zero_node);
06365 }
06366
06367 *maybe_tree = integer_one_node;
06368 expr_tree = build_int_2 (*ffetarget_text_character1
06369 (ffebld_constant_character1
06370 (ffebld_conter (arg))),
06371 0);
06372 TREE_TYPE (expr_tree) = tree_type;
06373 return expr_tree;
06374
06375 case FFEBLD_opSYMTER:
06376 case FFEBLD_opARRAYREF:
06377 case FFEBLD_opFUNCREF:
06378 case FFEBLD_opSUBSTR:
06379 ffecom_char_args_ (&expr_tree, &length_tree, arg);
06380
06381 if ((expr_tree == error_mark_node)
06382 || (length_tree == error_mark_node))
06383 {
06384 *maybe_tree = error_mark_node;
06385 return error_mark_node;
06386 }
06387
06388 if (integer_zerop (length_tree))
06389 {
06390 *maybe_tree = integer_zero_node;
06391 return convert (tree_type, integer_zero_node);
06392 }
06393
06394 expr_tree
06395 = ffecom_1 (INDIRECT_REF,
06396 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
06397 expr_tree);
06398 expr_tree
06399 = ffecom_2 (ARRAY_REF,
06400 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))),
06401 expr_tree,
06402 integer_one_node);
06403 expr_tree = convert (tree_type, expr_tree);
06404
06405 if (TREE_CODE (length_tree) == INTEGER_CST)
06406 *maybe_tree = integer_one_node;
06407 else
06408 *maybe_tree
06409 = ffecom_truth_value
06410 (ffecom_2 (GT_EXPR, integer_type_node,
06411 length_tree,
06412 ffecom_f2c_ftnlen_zero_node));
06413 return expr_tree;
06414
06415 case FFEBLD_opPAREN:
06416 case FFEBLD_opCONVERT:
06417 if (ffeinfo_size (ffebld_info (arg)) == 0)
06418 {
06419 *maybe_tree = integer_zero_node;
06420 return convert (tree_type, integer_zero_node);
06421 }
06422 return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
06423 maybe_tree);
06424
06425 case FFEBLD_opCONCATENATE:
06426 {
06427 tree maybe_left;
06428 tree maybe_right;
06429 tree expr_left;
06430 tree expr_right;
06431
06432 expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg),
06433 &maybe_left);
06434 expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg),
06435 &maybe_right);
06436 *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node,
06437 maybe_left,
06438 maybe_right);
06439 expr_tree = ffecom_3 (COND_EXPR, tree_type,
06440 maybe_left,
06441 expr_left,
06442 expr_right);
06443 return expr_tree;
06444 }
06445
06446 default:
06447 assert ("bad op in ICHAR" == NULL);
06448 return error_mark_node;
06449 }
06450 }
06451
06452
06453
06454
06455
06456
06457
06458
06459
06460
06461
06462 static tree
06463 ffecom_intrinsic_len_ (ffebld expr)
06464 {
06465 ffetargetCharacter1 val;
06466 tree length;
06467
06468 switch (ffebld_op (expr))
06469 {
06470 case FFEBLD_opCONTER:
06471 val = ffebld_constant_character1 (ffebld_conter (expr));
06472 length = build_int_2 (ffetarget_length_character1 (val), 0);
06473 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
06474 break;
06475
06476 case FFEBLD_opSYMTER:
06477 {
06478 ffesymbol s = ffebld_symter (expr);
06479 tree item;
06480
06481 item = ffesymbol_hook (s).decl_tree;
06482 if (item == NULL_TREE)
06483 {
06484 s = ffecom_sym_transform_ (s);
06485 item = ffesymbol_hook (s).decl_tree;
06486 }
06487 if (ffesymbol_kind (s) == FFEINFO_kindENTITY)
06488 {
06489 if (ffesymbol_size (s) == FFETARGET_charactersizeNONE)
06490 length = ffesymbol_hook (s).length_tree;
06491 else
06492 {
06493 length = build_int_2 (ffesymbol_size (s), 0);
06494 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
06495 }
06496 }
06497 else if (item == error_mark_node)
06498 length = error_mark_node;
06499 else
06500 length = NULL_TREE;
06501 }
06502 break;
06503
06504 case FFEBLD_opARRAYREF:
06505 length = ffecom_intrinsic_len_ (ffebld_left (expr));
06506 break;
06507
06508 case FFEBLD_opSUBSTR:
06509 {
06510 ffebld start;
06511 ffebld end;
06512 ffebld thing = ffebld_right (expr);
06513 tree start_tree;
06514 tree end_tree;
06515
06516 assert (ffebld_op (thing) == FFEBLD_opITEM);
06517 start = ffebld_head (thing);
06518 thing = ffebld_trail (thing);
06519 assert (ffebld_trail (thing) == NULL);
06520 end = ffebld_head (thing);
06521
06522 length = ffecom_intrinsic_len_ (ffebld_left (expr));
06523
06524 if (length == error_mark_node)
06525 break;
06526
06527 if (start == NULL)
06528 {
06529 if (end == NULL)
06530 ;
06531 else
06532 {
06533 length = convert (ffecom_f2c_ftnlen_type_node,
06534 ffecom_expr (end));
06535 }
06536 }
06537 else
06538 {
06539 start_tree = convert (ffecom_f2c_ftnlen_type_node,
06540 ffecom_expr (start));
06541
06542 if (start_tree == error_mark_node)
06543 {
06544 length = error_mark_node;
06545 break;
06546 }
06547
06548 if (end == NULL)
06549 {
06550 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
06551 ffecom_f2c_ftnlen_one_node,
06552 ffecom_2 (MINUS_EXPR,
06553 ffecom_f2c_ftnlen_type_node,
06554 length,
06555 start_tree));
06556 }
06557 else
06558 {
06559 end_tree = convert (ffecom_f2c_ftnlen_type_node,
06560 ffecom_expr (end));
06561
06562 if (end_tree == error_mark_node)
06563 {
06564 length = error_mark_node;
06565 break;
06566 }
06567
06568 length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
06569 ffecom_f2c_ftnlen_one_node,
06570 ffecom_2 (MINUS_EXPR,
06571 ffecom_f2c_ftnlen_type_node,
06572 end_tree, start_tree));
06573 }
06574 }
06575 }
06576 break;
06577
06578 case FFEBLD_opCONCATENATE:
06579 length
06580 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
06581 ffecom_intrinsic_len_ (ffebld_left (expr)),
06582 ffecom_intrinsic_len_ (ffebld_right (expr)));
06583 break;
06584
06585 case FFEBLD_opFUNCREF:
06586 case FFEBLD_opCONVERT:
06587 length = build_int_2 (ffebld_size (expr), 0);
06588 TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node;
06589 break;
06590
06591 default:
06592 assert ("bad op for single char arg expr" == NULL);
06593 length = ffecom_f2c_ftnlen_zero_node;
06594 break;
06595 }
06596
06597 assert (length != NULL_TREE);
06598
06599 return length;
06600 }
06601
06602
06603
06604
06605
06606
06607
06608 static void
06609 ffecom_let_char_ (tree dest_tree, tree dest_length,
06610 ffetargetCharacterSize dest_size, ffebld source)
06611 {
06612 ffecomConcatList_ catlist;
06613 tree source_length;
06614 tree source_tree;
06615 tree expr_tree;
06616
06617 if ((dest_tree == error_mark_node)
06618 || (dest_length == error_mark_node))
06619 return;
06620
06621 assert (dest_tree != NULL_TREE);
06622 assert (dest_length != NULL_TREE);
06623
06624
06625
06626
06627
06628
06629
06630
06631 while (ffebld_op (source) == FFEBLD_opCONVERT)
06632 source = ffebld_left (source);
06633
06634 catlist = ffecom_concat_list_new_ (source, dest_size);
06635 switch (ffecom_concat_list_count_ (catlist))
06636 {
06637 case 0:
06638 ffecom_concat_list_kill_ (catlist);
06639 source_tree = null_pointer_node;
06640 source_length = ffecom_f2c_ftnlen_zero_node;
06641 expr_tree = build_tree_list (NULL_TREE, dest_tree);
06642 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
06643 TREE_CHAIN (TREE_CHAIN (expr_tree))
06644 = build_tree_list (NULL_TREE, dest_length);
06645 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
06646 = build_tree_list (NULL_TREE, source_length);
06647
06648 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
06649 TREE_SIDE_EFFECTS (expr_tree) = 1;
06650
06651 expand_expr_stmt (expr_tree);
06652
06653 return;
06654
06655 case 1:
06656 ffecom_char_args_ (&source_tree, &source_length,
06657 ffecom_concat_list_expr_ (catlist, 0));
06658 ffecom_concat_list_kill_ (catlist);
06659 assert (source_tree != NULL_TREE);
06660 assert (source_length != NULL_TREE);
06661
06662 if ((source_tree == error_mark_node)
06663 || (source_length == error_mark_node))
06664 return;
06665
06666 if (dest_size == 1)
06667 {
06668 dest_tree
06669 = ffecom_1 (INDIRECT_REF,
06670 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
06671 (dest_tree))),
06672 dest_tree);
06673 dest_tree
06674 = ffecom_2 (ARRAY_REF,
06675 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
06676 (dest_tree))),
06677 dest_tree,
06678 integer_one_node);
06679 source_tree
06680 = ffecom_1 (INDIRECT_REF,
06681 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
06682 (source_tree))),
06683 source_tree);
06684 source_tree
06685 = ffecom_2 (ARRAY_REF,
06686 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE
06687 (source_tree))),
06688 source_tree,
06689 integer_one_node);
06690
06691 expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree);
06692
06693 expand_expr_stmt (expr_tree);
06694
06695 return;
06696 }
06697
06698 expr_tree = build_tree_list (NULL_TREE, dest_tree);
06699 TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree);
06700 TREE_CHAIN (TREE_CHAIN (expr_tree))
06701 = build_tree_list (NULL_TREE, dest_length);
06702 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
06703 = build_tree_list (NULL_TREE, source_length);
06704
06705 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree, NULL_TREE);
06706 TREE_SIDE_EFFECTS (expr_tree) = 1;
06707
06708 expand_expr_stmt (expr_tree);
06709
06710 return;
06711
06712 default:
06713 break;
06714 }
06715
06716
06717
06718 {
06719 int count = ffecom_concat_list_count_ (catlist);
06720 int i;
06721 tree lengths;
06722 tree items;
06723 tree length_array;
06724 tree item_array;
06725 tree citem;
06726 tree clength;
06727
06728 #ifdef HOHO
06729 length_array
06730 = lengths
06731 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
06732 FFETARGET_charactersizeNONE, count, TRUE);
06733 item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node,
06734 FFETARGET_charactersizeNONE,
06735 count, TRUE);
06736 #else
06737 {
06738 tree hook;
06739
06740 hook = ffebld_nonter_hook (source);
06741 assert (hook);
06742 assert (TREE_CODE (hook) == TREE_VEC);
06743 assert (TREE_VEC_LENGTH (hook) == 2);
06744 length_array = lengths = TREE_VEC_ELT (hook, 0);
06745 item_array = items = TREE_VEC_ELT (hook, 1);
06746 }
06747 #endif
06748
06749 for (i = 0; i < count; ++i)
06750 {
06751 ffecom_char_args_ (&citem, &clength,
06752 ffecom_concat_list_expr_ (catlist, i));
06753 if ((citem == error_mark_node)
06754 || (clength == error_mark_node))
06755 {
06756 ffecom_concat_list_kill_ (catlist);
06757 return;
06758 }
06759
06760 items
06761 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
06762 ffecom_modify (void_type_node,
06763 ffecom_2 (ARRAY_REF,
06764 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
06765 item_array,
06766 build_int_2 (i, 0)),
06767 citem),
06768 items);
06769 lengths
06770 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
06771 ffecom_modify (void_type_node,
06772 ffecom_2 (ARRAY_REF,
06773 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
06774 length_array,
06775 build_int_2 (i, 0)),
06776 clength),
06777 lengths);
06778 }
06779
06780 expr_tree = build_tree_list (NULL_TREE, dest_tree);
06781 TREE_CHAIN (expr_tree)
06782 = build_tree_list (NULL_TREE,
06783 ffecom_1 (ADDR_EXPR,
06784 build_pointer_type (TREE_TYPE (items)),
06785 items));
06786 TREE_CHAIN (TREE_CHAIN (expr_tree))
06787 = build_tree_list (NULL_TREE,
06788 ffecom_1 (ADDR_EXPR,
06789 build_pointer_type (TREE_TYPE (lengths)),
06790 lengths));
06791 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))
06792 = build_tree_list
06793 (NULL_TREE,
06794 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
06795 convert (ffecom_f2c_ftnlen_type_node,
06796 build_int_2 (count, 0))));
06797 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))))
06798 = build_tree_list (NULL_TREE, dest_length);
06799
06800 expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree, NULL_TREE);
06801 TREE_SIDE_EFFECTS (expr_tree) = 1;
06802
06803 expand_expr_stmt (expr_tree);
06804 }
06805
06806 ffecom_concat_list_kill_ (catlist);
06807 }
06808
06809
06810
06811
06812
06813
06814
06815
06816
06817 static void
06818 ffecom_make_gfrt_ (ffecomGfrt ix)
06819 {
06820 tree t;
06821 tree ttype;
06822
06823 switch (ffecom_gfrt_type_[ix])
06824 {
06825 case FFECOM_rttypeVOID_:
06826 ttype = void_type_node;
06827 break;
06828
06829 case FFECOM_rttypeVOIDSTAR_:
06830 ttype = TREE_TYPE (null_pointer_node);
06831 break;
06832
06833 case FFECOM_rttypeFTNINT_:
06834 ttype = ffecom_f2c_ftnint_type_node;
06835 break;
06836
06837 case FFECOM_rttypeINTEGER_:
06838 ttype = ffecom_f2c_integer_type_node;
06839 break;
06840
06841 case FFECOM_rttypeLONGINT_:
06842 ttype = ffecom_f2c_longint_type_node;
06843 break;
06844
06845 case FFECOM_rttypeLOGICAL_:
06846 ttype = ffecom_f2c_logical_type_node;
06847 break;
06848
06849 case FFECOM_rttypeREAL_F2C_:
06850 ttype = double_type_node;
06851 break;
06852
06853 case FFECOM_rttypeREAL_GNU_:
06854 ttype = float_type_node;
06855 break;
06856
06857 case FFECOM_rttypeCOMPLEX_F2C_:
06858 ttype = void_type_node;
06859 break;
06860
06861 case FFECOM_rttypeCOMPLEX_GNU_:
06862 ttype = ffecom_f2c_complex_type_node;
06863 break;
06864
06865 case FFECOM_rttypeDOUBLE_:
06866 ttype = double_type_node;
06867 break;
06868
06869 case FFECOM_rttypeDOUBLEREAL_:
06870 ttype = ffecom_f2c_doublereal_type_node;
06871 break;
06872
06873 case FFECOM_rttypeDBLCMPLX_F2C_:
06874 ttype = void_type_node;
06875 break;
06876
06877 case FFECOM_rttypeDBLCMPLX_GNU_:
06878 ttype = ffecom_f2c_doublecomplex_type_node;
06879 break;
06880
06881 case FFECOM_rttypeCHARACTER_:
06882 ttype = void_type_node;
06883 break;
06884
06885 default:
06886 ttype = NULL;
06887 assert ("bad rttype" == NULL);
06888 break;
06889 }
06890
06891 ttype = build_function_type (ttype, NULL_TREE);
06892 t = build_decl (FUNCTION_DECL,
06893 get_identifier (ffecom_gfrt_name_[ix]),
06894 ttype);
06895 DECL_EXTERNAL (t) = 1;
06896 TREE_READONLY (t) = ffecom_gfrt_const_[ix] ? 1 : 0;
06897 TREE_PUBLIC (t) = 1;
06898 TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0;
06899
06900
06901
06902 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_volatile_[ix] : 1);
06903
06904
06905
06906 assert (ffecom_gfrt_const_[ix] ? !ffecom_gfrt_complex_[ix] : 1);
06907
06908 t = start_decl (t, TRUE);
06909
06910 finish_decl (t, NULL_TREE, TRUE);
06911
06912 ffecom_gfrt_[ix] = t;
06913 }
06914
06915
06916
06917 static void
06918 ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st)
06919 {
06920 ffesymbol s = ffestorag_symbol (st);
06921
06922 if (ffesymbol_namelisted (s))
06923 ffecom_member_namelisted_ = TRUE;
06924 }
06925
06926
06927
06928
06929
06930 static void
06931 ffecom_member_phase2_ (ffestorag mst, ffestorag st)
06932 {
06933 ffesymbol s;
06934 tree t;
06935 tree mt;
06936 tree type;
06937
06938 if ((mst == NULL)
06939 || ((mt = ffestorag_hook (mst)) == NULL)
06940 || (mt == error_mark_node))
06941 return;
06942
06943 if ((st == NULL)
06944 || ((s = ffestorag_symbol (st)) == NULL))
06945 return;
06946
06947 type = ffecom_type_localvar_ (s,
06948 ffesymbol_basictype (s),
06949 ffesymbol_kindtype (s));
06950 if (type == error_mark_node)
06951 return;
06952
06953 t = build_decl (VAR_DECL,
06954 ffecom_get_identifier_ (ffesymbol_text (s)),
06955 type);
06956
06957 TREE_STATIC (t) = TREE_STATIC (mt);
06958 DECL_INITIAL (t) = NULL_TREE;
06959 TREE_ASM_WRITTEN (t) = 1;
06960 TREE_USED (t) = 1;
06961
06962 SET_DECL_RTL (t,
06963 gen_rtx (MEM, TYPE_MODE (type),
06964 plus_constant (XEXP (DECL_RTL (mt), 0),
06965 ffestorag_modulo (mst)
06966 + ffestorag_offset (st)
06967 - ffestorag_offset (mst))));
06968
06969 t = start_decl (t, FALSE);
06970
06971 finish_decl (t, NULL_TREE, FALSE);
06972 }
06973
06974
06975
06976
06977 static void
06978 ffecom_prepare_let_char_ (ffetargetCharacterSize dest_size, ffebld source)
06979 {
06980 ffecomConcatList_ catlist;
06981 int count;
06982 int i;
06983 tree ltmp;
06984 tree itmp;
06985 tree tempvar = NULL_TREE;
06986
06987 while (ffebld_op (source) == FFEBLD_opCONVERT)
06988 source = ffebld_left (source);
06989
06990 catlist = ffecom_concat_list_new_ (source, dest_size);
06991 count = ffecom_concat_list_count_ (catlist);
06992
06993 if (count >= 2)
06994 {
06995 ltmp
06996 = ffecom_make_tempvar ("let_char_len", ffecom_f2c_ftnlen_type_node,
06997 FFETARGET_charactersizeNONE, count);
06998 itmp
06999 = ffecom_make_tempvar ("let_char_item", ffecom_f2c_address_type_node,
07000 FFETARGET_charactersizeNONE, count);
07001
07002 tempvar = make_tree_vec (2);
07003 TREE_VEC_ELT (tempvar, 0) = ltmp;
07004 TREE_VEC_ELT (tempvar, 1) = itmp;
07005 }
07006
07007 for (i = 0; i < count; ++i)
07008 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist, i));
07009
07010 ffecom_concat_list_kill_ (catlist);
07011
07012 if (tempvar)
07013 {
07014 ffebld_nonter_set_hook (source, tempvar);
07015 current_binding_level->prep_state = 1;
07016 }
07017 }
07018
07019
07020
07021
07022
07023
07024
07025
07026
07027
07028
07029 static void
07030 ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
07031 {
07032 ffebld dummy;
07033 ffebld dumlist;
07034 ffesymbol s;
07035 tree parm;
07036
07037 ffecom_transform_only_dummies_ = TRUE;
07038
07039
07040
07041 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
07042 {
07043 dummy = ffebld_head (dumlist);
07044 switch (ffebld_op (dummy))
07045 {
07046 case FFEBLD_opSTAR:
07047 case FFEBLD_opANY:
07048 continue;
07049
07050 default:
07051 break;
07052 }
07053 assert (ffebld_op (dummy) == FFEBLD_opSYMTER);
07054 s = ffebld_symter (dummy);
07055 parm = ffesymbol_hook (s).decl_tree;
07056 if (parm == NULL_TREE)
07057 {
07058 s = ffecom_sym_transform_ (s);
07059 parm = ffesymbol_hook (s).decl_tree;
07060 assert (parm != NULL_TREE);
07061 }
07062 if (parm != error_mark_node)
07063 push_parm_decl (parm);
07064 }
07065
07066
07067
07068 for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist))
07069 {
07070 dummy = ffebld_head (dumlist);
07071 switch (ffebld_op (dummy))
07072 {
07073 case FFEBLD_opSTAR:
07074 case FFEBLD_opANY:
07075 continue;
07076
07077
07078 default:
07079 break;
07080 }
07081 s = ffebld_symter (dummy);
07082 if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER)
07083 continue;
07084 if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE))
07085 continue;
07086
07087 if (ffesymbol_kind (s) != FFEINFO_kindENTITY)
07088 continue;
07089 parm = ffesymbol_hook (s).length_tree;
07090 assert (parm != NULL_TREE);
07091 if (parm != error_mark_node)
07092 push_parm_decl (parm);
07093 }
07094
07095 ffecom_transform_only_dummies_ = FALSE;
07096 }
07097
07098
07099
07100
07101
07102
07103 static void
07104 ffecom_start_progunit_ ()
07105 {
07106 ffesymbol fn = ffecom_primary_entry_;
07107 ffebld arglist;
07108 tree id;
07109 tree type;
07110 tree result;
07111 ffeinfoBasictype bt;
07112 ffeinfoKindtype kt;
07113 ffeglobal g;
07114 ffeglobalType gt;
07115 ffeglobalType egt = FFEGLOBAL_type;
07116 bool charfunc;
07117 bool cmplxfunc;
07118 bool altentries = (ffecom_num_entrypoints_ != 0);
07119 bool multi
07120 = altentries
07121 && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
07122 && (ffecom_master_bt_ == FFEINFO_basictypeNONE);
07123 bool main_program = FALSE;
07124 int old_lineno = lineno;
07125 const char *old_input_filename = input_filename;
07126
07127 assert (fn != NULL);
07128 assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
07129
07130 input_filename = ffesymbol_where_filename (fn);
07131 lineno = ffesymbol_where_filelinenum (fn);
07132
07133 switch (ffecom_primary_entry_kind_)
07134 {
07135 case FFEINFO_kindPROGRAM:
07136 main_program = TRUE;
07137 gt = FFEGLOBAL_typeMAIN;
07138 bt = FFEINFO_basictypeNONE;
07139 kt = FFEINFO_kindtypeNONE;
07140 type = ffecom_tree_fun_type_void;
07141 charfunc = FALSE;
07142 cmplxfunc = FALSE;
07143 break;
07144
07145 case FFEINFO_kindBLOCKDATA:
07146 gt = FFEGLOBAL_typeBDATA;
07147 bt = FFEINFO_basictypeNONE;
07148 kt = FFEINFO_kindtypeNONE;
07149 type = ffecom_tree_fun_type_void;
07150 charfunc = FALSE;
07151 cmplxfunc = FALSE;
07152 break;
07153
07154 case FFEINFO_kindFUNCTION:
07155 gt = FFEGLOBAL_typeFUNC;
07156 egt = FFEGLOBAL_typeEXT;
07157 bt = ffesymbol_basictype (fn);
07158 kt = ffesymbol_kindtype (fn);
07159 if (bt == FFEINFO_basictypeNONE)
07160 {
07161 ffeimplic_establish_symbol (fn);
07162 if (ffesymbol_funcresult (fn) != NULL)
07163 ffeimplic_establish_symbol (ffesymbol_funcresult (fn));
07164 bt = ffesymbol_basictype (fn);
07165 kt = ffesymbol_kindtype (fn);
07166 }
07167
07168 if (multi)
07169 charfunc = cmplxfunc = FALSE;
07170 else if (bt == FFEINFO_basictypeCHARACTER)
07171 charfunc = TRUE, cmplxfunc = FALSE;
07172 else if ((bt == FFEINFO_basictypeCOMPLEX)
07173 && ffesymbol_is_f2c (fn)
07174 && !altentries)
07175 charfunc = FALSE, cmplxfunc = TRUE;
07176 else
07177 charfunc = cmplxfunc = FALSE;
07178
07179 if (multi || charfunc)
07180 type = ffecom_tree_fun_type_void;
07181 else if (ffesymbol_is_f2c (fn) && !altentries)
07182 type = ffecom_tree_fun_type[bt][kt];
07183 else
07184 type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
07185
07186 if ((type == NULL_TREE)
07187 || (TREE_TYPE (type) == NULL_TREE))
07188 type = ffecom_tree_fun_type_void;
07189 break;
07190
07191 case FFEINFO_kindSUBROUTINE:
07192 gt = FFEGLOBAL_typeSUBR;
07193 egt = FFEGLOBAL_typeEXT;
07194 bt = FFEINFO_basictypeNONE;
07195 kt = FFEINFO_kindtypeNONE;
07196 if (ffecom_is_altreturning_)
07197 type = ffecom_tree_subr_type;
07198 else
07199 type = ffecom_tree_fun_type_void;
07200 charfunc = FALSE;
07201 cmplxfunc = FALSE;
07202 break;
07203
07204 default:
07205 assert ("say what??" == NULL);
07206
07207 case FFEINFO_kindANY:
07208 gt = FFEGLOBAL_typeANY;
07209 bt = FFEINFO_basictypeNONE;
07210 kt = FFEINFO_kindtypeNONE;
07211 type = error_mark_node;
07212 charfunc = FALSE;
07213 cmplxfunc = FALSE;
07214 break;
07215 }
07216
07217 if (altentries)
07218 {
07219 id = ffecom_get_invented_identifier ("__g77_masterfun_%s",
07220 ffesymbol_text (fn));
07221 }
07222 #if FFETARGET_isENFORCED_MAIN
07223 else if (main_program)
07224 id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME);
07225 #endif
07226 else
07227 id = ffecom_get_external_identifier_ (fn);
07228
07229 start_function (id,
07230 type,
07231 0,
07232 !altentries);
07233
07234 TREE_USED (current_function_decl) = 1;
07235
07236 if (!altentries
07237 && ((g = ffesymbol_global (fn)) != NULL)
07238 && ((ffeglobal_type (g) == gt)
07239 || (ffeglobal_type (g) == egt)))
07240 {
07241 ffeglobal_set_hook (g, current_function_decl);
07242 }
07243
07244
07245
07246
07247
07248 if (altentries)
07249 {
07250 ffecom_which_entrypoint_decl_
07251 = build_decl (PARM_DECL,
07252 ffecom_get_invented_identifier ("__g77_%s",
07253 "which_entrypoint"),
07254 integer_type_node);
07255 push_parm_decl (ffecom_which_entrypoint_decl_);
07256 }
07257
07258 if (charfunc
07259 || cmplxfunc
07260 || multi)
07261 {
07262 tree type;
07263 tree length;
07264
07265 if (charfunc)
07266 type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt];
07267 else if (cmplxfunc)
07268 type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt];
07269 else
07270 type = ffecom_multi_type_node_;
07271
07272 result = ffecom_get_invented_identifier ("__g77_%s", "result");
07273
07274
07275
07276 if (charfunc)
07277 length = ffecom_char_enhance_arg_ (&type, fn);
07278 else
07279 length = NULL_TREE;
07280
07281 type = build_pointer_type (type);
07282 result = build_decl (PARM_DECL, result, type);
07283
07284 push_parm_decl (result);
07285 if (multi)
07286 ffecom_multi_retval_ = result;
07287 else
07288 ffecom_func_result_ = result;
07289
07290 if (charfunc)
07291 {
07292 push_parm_decl (length);
07293 ffecom_func_length_ = length;
07294 }
07295 }
07296
07297 if (ffecom_primary_entry_is_proc_)
07298 {
07299 if (altentries)
07300 arglist = ffecom_master_arglist_;
07301 else
07302 arglist = ffesymbol_dummyargs (fn);
07303 ffecom_push_dummy_decls_ (arglist, FALSE);
07304 }
07305
07306 if (TREE_CODE (current_function_decl) != ERROR_MARK)
07307 store_parm_decls (main_program ? 1 : 0);
07308
07309 ffecom_start_compstmt ();
07310
07311 current_binding_level->prep_state = 2;
07312
07313 lineno = old_lineno;
07314 input_filename = old_input_filename;
07315
07316
07317
07318
07319
07320
07321 if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
07322 ffesymbol_drive (ffecom_finish_symbol_transform_);
07323 }
07324
07325
07326
07327
07328
07329
07330
07331
07332
07333 static ffesymbol
07334 ffecom_sym_transform_ (ffesymbol s)
07335 {
07336 tree t;
07337 tree tlen;
07338 bool addr;
07339 ffeinfoBasictype bt;
07340 ffeinfoKindtype kt;
07341 ffeglobal g;
07342 int old_lineno = lineno;
07343 const char *old_input_filename = input_filename;
07344
07345
07346
07347
07348
07349
07350
07351
07352
07353
07354 if (! ffecom_transform_only_dummies_
07355 && ffesymbol_assigned (s)
07356 && ! ffesymbol_hook (s).assign_tree)
07357 s = ffecom_sym_transform_assign_ (s);
07358
07359 if (ffesymbol_sfdummyparent (s) == NULL)
07360 {
07361 input_filename = ffesymbol_where_filename (s);
07362 lineno = ffesymbol_where_filelinenum (s);
07363 }
07364 else
07365 {
07366 ffesymbol sf = ffesymbol_sfdummyparent (s);
07367
07368 input_filename = ffesymbol_where_filename (sf);
07369 lineno = ffesymbol_where_filelinenum (sf);
07370 }
07371
07372 bt = ffeinfo_basictype (ffebld_info (s));
07373 kt = ffeinfo_kindtype (ffebld_info (s));
07374
07375 t = NULL_TREE;
07376 tlen = NULL_TREE;
07377 addr = FALSE;
07378
07379 switch (ffesymbol_kind (s))
07380 {
07381 case FFEINFO_kindNONE:
07382 switch (ffesymbol_where (s))
07383 {
07384 case FFEINFO_whereDUMMY:
07385 assert (ffecom_transform_only_dummies_);
07386
07387
07388
07389
07390
07391
07392
07393 t = build_decl (PARM_DECL,
07394 ffecom_get_identifier_ (ffesymbol_text (s)),
07395 ffecom_tree_ptr_to_subr_type);
07396 DECL_ARTIFICIAL (t) = 1;
07397 addr = TRUE;
07398 break;
07399
07400 case FFEINFO_whereGLOBAL:
07401 assert (!ffecom_transform_only_dummies_);
07402
07403 if (((g = ffesymbol_global (s)) != NULL)
07404 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
07405 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
07406 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
07407 && (ffeglobal_hook (g) != NULL_TREE)
07408 && ffe_is_globals ())
07409 {
07410 t = ffeglobal_hook (g);
07411 break;
07412 }
07413
07414 t = build_decl (FUNCTION_DECL,
07415 ffecom_get_external_identifier_ (s),
07416 ffecom_tree_subr_type);
07417 DECL_EXTERNAL (t) = 1;
07418 TREE_PUBLIC (t) = 1;
07419
07420 t = start_decl (t, FALSE);
07421 finish_decl (t, NULL_TREE, FALSE);
07422
07423 if ((g != NULL)
07424 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
07425 || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
07426 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
07427 ffeglobal_set_hook (g, t);
07428
07429 ffecom_save_tree_forever (t);
07430
07431 break;
07432
07433 default:
07434 assert ("NONE where unexpected" == NULL);
07435
07436 case FFEINFO_whereANY:
07437 break;
07438 }
07439 break;
07440
07441 case FFEINFO_kindENTITY:
07442 switch (ffeinfo_where (ffesymbol_info (s)))
07443 {
07444
07445 case FFEINFO_whereCONSTANT:
07446
07447 assert (!ffecom_transform_only_dummies_);
07448 t = error_mark_node;
07449 break;
07450
07451 case FFEINFO_whereLOCAL:
07452 assert (!ffecom_transform_only_dummies_);
07453
07454 {
07455 ffestorag st = ffesymbol_storage (s);
07456 tree type;
07457
07458 if ((st != NULL)
07459 && (ffestorag_size (st) == 0))
07460 {
07461 t = error_mark_node;
07462 break;
07463 }
07464
07465 type = ffecom_type_localvar_ (s, bt, kt);
07466
07467 if (type == error_mark_node)
07468 {
07469 t = error_mark_node;
07470 break;
07471 }
07472
07473 if ((st != NULL)
07474 && (ffestorag_parent (st) != NULL))
07475 {
07476 ffestorag est;
07477 tree et;
07478 ffetargetOffset offset;
07479
07480 est = ffestorag_parent (st);
07481 ffecom_transform_equiv_ (est);
07482
07483 et = ffestorag_hook (est);
07484 assert (et != NULL_TREE);
07485
07486 if (! TREE_STATIC (et))
07487 put_var_into_stack (et);
07488
07489 offset = ffestorag_modulo (est)
07490 + ffestorag_offset (ffesymbol_storage (s))
07491 - ffestorag_offset (est);
07492
07493 ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset);
07494
07495
07496
07497 t = convert (string_type_node,
07498 ffecom_1 (ADDR_EXPR,
07499 build_pointer_type (TREE_TYPE (et)),
07500 et));
07501 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
07502 t,
07503 build_int_2 (offset, 0));
07504 t = convert (build_pointer_type (type),
07505 t);
07506 TREE_CONSTANT (t) = staticp (et);
07507
07508 addr = TRUE;
07509 }
07510 else
07511 {
07512 tree initexpr;
07513 bool init = ffesymbol_is_init (s);
07514
07515 t = build_decl (VAR_DECL,
07516 ffecom_get_identifier_ (ffesymbol_text (s)),
07517 type);
07518
07519 if (init
07520 || ffesymbol_namelisted (s)
07521 #ifdef FFECOM_sizeMAXSTACKITEM
07522 || ((st != NULL)
07523 && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM))
07524 #endif
07525 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
07526 && (ffecom_primary_entry_kind_
07527 != FFEINFO_kindBLOCKDATA)
07528 && (ffesymbol_is_save (s) || ffe_is_saveall ())))
07529 TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE);
07530 else
07531 TREE_STATIC (t) = 0;
07532
07533 if (init || ffe_is_init_local_zero ())
07534 DECL_INITIAL (t) = error_mark_node;
07535
07536
07537
07538 if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG)
07539 DECL_IN_SYSTEM_HEADER (t) = 1;
07540
07541 t = start_decl (t, FALSE);
07542
07543 if (init)
07544 {
07545 if (ffesymbol_init (s) != NULL)
07546 initexpr = ffecom_expr (ffesymbol_init (s));
07547 else
07548 initexpr = ffecom_init_zero_ (t);
07549 }
07550 else if (ffe_is_init_local_zero ())
07551 initexpr = ffecom_init_zero_ (t);
07552 else
07553 initexpr = NULL_TREE;
07554
07555 finish_decl (t, initexpr, FALSE);
07556
07557 if (st != NULL && DECL_SIZE (t) != error_mark_node)
07558 {
07559 assert (TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST);
07560 assert (0 == compare_tree_int (DECL_SIZE_UNIT (t),
07561 ffestorag_size (st)));
07562 }
07563 }
07564 }
07565 break;
07566
07567 case FFEINFO_whereRESULT:
07568 assert (!ffecom_transform_only_dummies_);
07569
07570 if (bt == FFEINFO_basictypeCHARACTER)
07571 {
07572
07573 t = ffecom_func_result_;
07574 tlen = ffecom_func_length_;
07575 addr = TRUE;
07576 break;
07577 }
07578 if ((ffecom_num_entrypoints_ == 0)
07579 && (bt == FFEINFO_basictypeCOMPLEX)
07580 && (ffesymbol_is_f2c (ffecom_primary_entry_)))
07581 {
07582
07583 t = ffecom_func_result_;
07584 addr = TRUE;
07585 break;
07586 }
07587 if (ffecom_func_result_ != NULL_TREE)
07588 {
07589 t = ffecom_func_result_;
07590 break;
07591 }
07592 if ((ffecom_num_entrypoints_ != 0)
07593 && (ffecom_master_bt_ == FFEINFO_basictypeNONE))
07594 {
07595 assert (ffecom_multi_retval_ != NULL_TREE);
07596 t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_,
07597 ffecom_multi_retval_);
07598 t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt],
07599 t, ffecom_multi_fields_[bt][kt]);
07600
07601 break;
07602 }
07603
07604 t = build_decl (VAR_DECL,
07605 ffecom_get_identifier_ (ffesymbol_text (s)),
07606 ffecom_tree_type[bt][kt]);
07607 TREE_STATIC (t) = 0;
07608 t = start_decl (t, FALSE);
07609 finish_decl (t, NULL_TREE, FALSE);
07610
07611 ffecom_func_result_ = t;
07612
07613 break;
07614
07615 case FFEINFO_whereDUMMY:
07616 {
07617 tree type;
07618 ffebld dl;
07619 ffebld dim;
07620 tree low;
07621 tree high;
07622 tree old_sizes;
07623 bool adjustable = FALSE;
07624
07625 type = ffecom_tree_type[bt][kt];
07626 if (ffesymbol_sfdummyparent (s) != NULL)
07627 {
07628 if (current_function_decl == ffecom_outer_function_decl_)
07629 {
07630
07631 break;
07632 }
07633 t = ffecom_get_identifier_ (ffesymbol_text
07634 (ffesymbol_sfdummyparent (s)));
07635 }
07636 else
07637 t = ffecom_get_identifier_ (ffesymbol_text (s));
07638
07639 assert (ffecom_transform_only_dummies_);
07640
07641 old_sizes = get_pending_sizes ();
07642 put_pending_sizes (old_sizes);
07643
07644 if (bt == FFEINFO_basictypeCHARACTER)
07645 tlen = ffecom_char_enhance_arg_ (&type, s);
07646 type = ffecom_check_size_overflow_ (s, type, TRUE);
07647
07648 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
07649 {
07650 if (type == error_mark_node)
07651 break;
07652
07653 dim = ffebld_head (dl);
07654 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
07655 if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_)
07656 low = ffecom_integer_one_node;
07657 else
07658 low = ffecom_expr (ffebld_left (dim));
07659 assert (ffebld_right (dim) != NULL);
07660 if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR)
07661 || ffecom_doing_entry_)
07662 {
07663
07664
07665
07666
07667
07668
07669
07670
07671 high = NULL;
07672 }
07673 else
07674 high = ffecom_expr (ffebld_right (dim));
07675
07676
07677
07678
07679
07680
07681
07682
07683
07684
07685
07686
07687
07688
07689
07690
07691
07692
07693
07694
07695
07696
07697
07698
07699
07700
07701
07702
07703
07704
07705
07706
07707
07708
07709
07710
07711
07712
07713
07714
07715
07716
07717
07718
07719
07720
07721
07722
07723
07724
07725
07726
07727
07728
07729
07730
07731
07732
07733
07734
07735
07736
07737
07738
07739
07740
07741
07742
07743
07744
07745
07746
07747
07748
07749
07750
07751
07752
07753
07754
07755
07756
07757
07758
07759
07760
07761
07762
07763
07764
07765
07766
07767
07768
07769
07770
07771
07772
07773
07774
07775
07776
07777
07778
07779
07780
07781
07782
07783
07784
07785
07786
07787
07788
07789
07790
07791
07792
07793
07794
07795
07796
07797
07798
07799
07800
07801
07802
07803
07804
07805
07806
07807
07808
07809
07810 if (!adjustable
07811 && ((TREE_CODE (low) != INTEGER_CST)
07812 || (high && TREE_CODE (high) != INTEGER_CST)))
07813 adjustable = TRUE;
07814
07815 #if 0
07816 if (TREE_CODE (low) != INTEGER_CST)
07817 low = ffecom_3 (COND_EXPR, integer_type_node,
07818 ffecom_adjarray_passed_ (s),
07819 low,
07820 ffecom_integer_zero_node);
07821
07822 if (high && TREE_CODE (high) != INTEGER_CST)
07823 high = ffecom_3 (COND_EXPR, integer_type_node,
07824 ffecom_adjarray_passed_ (s),
07825 high,
07826 ffecom_integer_zero_node);
07827 #endif
07828
07829
07830
07831
07832 if (TREE_CODE (low) != INTEGER_CST)
07833 low = variable_size (low);
07834
07835
07836
07837
07838 if (high && TREE_CODE (high) != INTEGER_CST)
07839 high = variable_size (high);
07840
07841 type
07842 = build_array_type
07843 (type,
07844 build_range_type (ffecom_integer_type_node,
07845 low, high));
07846 type = ffecom_check_size_overflow_ (s, type, TRUE);
07847 }
07848
07849 if (type == error_mark_node)
07850 {
07851 t = error_mark_node;
07852 break;
07853 }
07854
07855 if ((ffesymbol_sfdummyparent (s) == NULL)
07856 || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER))
07857 {
07858 type = build_pointer_type (type);
07859 addr = TRUE;
07860 }
07861
07862 t = build_decl (PARM_DECL, t, type);
07863 DECL_ARTIFICIAL (t) = 1;
07864
07865
07866
07867
07868 if (ffesymbol_numentries (s)
07869 == (ffecom_num_entrypoints_ + 1))
07870 break;
07871
07872 #if 1
07873
07874
07875
07876
07877
07878
07879
07880 {
07881 tree sizes = get_pending_sizes ();
07882 tree tem;
07883
07884 for (tem = sizes;
07885 tem != old_sizes;
07886 tem = TREE_CHAIN (tem))
07887 {
07888 tree temv = TREE_VALUE (tem);
07889
07890 if (sizes == tem)
07891 sizes = temv;
07892 else
07893 sizes
07894 = ffecom_2 (COMPOUND_EXPR,
07895 TREE_TYPE (sizes),
07896 temv,
07897 sizes);
07898 }
07899
07900 if (sizes != tem)
07901 {
07902 sizes
07903 = ffecom_3 (COND_EXPR,
07904 TREE_TYPE (sizes),
07905 ffecom_2 (NE_EXPR,
07906 integer_type_node,
07907 t,
07908 null_pointer_node),
07909 sizes,
07910 convert (TREE_TYPE (sizes),
07911 integer_zero_node));
07912 sizes = ffecom_save_tree (sizes);
07913
07914 sizes
07915 = tree_cons (NULL_TREE, sizes, tem);
07916 }
07917
07918 if (sizes)
07919 put_pending_sizes (sizes);
07920 }
07921
07922 #else
07923 #if 0
07924 if (adjustable
07925 && (ffesymbol_numentries (s)
07926 != ffecom_num_entrypoints_ + 1))
07927 DECL_SOMETHING (t)
07928 = ffecom_2 (NE_EXPR, integer_type_node,
07929 t,
07930 null_pointer_node);
07931 #else
07932 #if 0
07933 if (adjustable
07934 && (ffesymbol_numentries (s)
07935 != ffecom_num_entrypoints_ + 1))
07936 {
07937 ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED);
07938 ffebad_here (0, ffesymbol_where_line (s),
07939 ffesymbol_where_column (s));
07940 ffebad_string (ffesymbol_text (s));
07941 ffebad_finish ();
07942 }
07943 #endif
07944 #endif
07945 #endif
07946 }
07947 break;
07948
07949 case FFEINFO_whereCOMMON:
07950 {
07951 ffesymbol cs;
07952 ffeglobal cg;
07953 tree ct;
07954 ffestorag st = ffesymbol_storage (s);
07955 tree type;
07956
07957 cs = ffesymbol_common (s);
07958 if (st != NULL)
07959 {
07960 ffecom_transform_common_ (cs);
07961 st = ffesymbol_storage (s);
07962 }
07963
07964 type = ffecom_type_localvar_ (s, bt, kt);
07965
07966 cg = ffesymbol_global (cs);
07967 if ((cg == NULL)
07968 || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON))
07969 ct = NULL_TREE;
07970 else
07971 ct = ffeglobal_hook (cg);
07972
07973 if ((ct == NULL_TREE)
07974 || (st == NULL)
07975 || (type == error_mark_node))
07976 t = error_mark_node;
07977 else
07978 {
07979 ffetargetOffset offset;
07980 ffestorag cst;
07981
07982 cst = ffestorag_parent (st);
07983 assert (cst == ffesymbol_storage (cs));
07984
07985 offset = ffestorag_modulo (cst)
07986 + ffestorag_offset (st)
07987 - ffestorag_offset (cst);
07988
07989 ffecom_debug_kludge_ (ct, "COMMON", s, type, offset);
07990
07991
07992
07993 t = convert (string_type_node,
07994 ffecom_1 (ADDR_EXPR,
07995 build_pointer_type (TREE_TYPE (ct)),
07996 ct));
07997 t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
07998 t,
07999 build_int_2 (offset, 0));
08000 t = convert (build_pointer_type (type),
08001 t);
08002 TREE_CONSTANT (t) = 1;
08003
08004 addr = TRUE;
08005 }
08006 }
08007 break;
08008
08009 case FFEINFO_whereIMMEDIATE:
08010 case FFEINFO_whereGLOBAL:
08011 case FFEINFO_whereFLEETING:
08012 case FFEINFO_whereFLEETING_CADDR:
08013 case FFEINFO_whereFLEETING_IADDR:
08014 case FFEINFO_whereINTRINSIC:
08015 case FFEINFO_whereCONSTANT_SUBOBJECT:
08016 default:
08017 assert ("ENTITY where unheard of" == NULL);
08018
08019 case FFEINFO_whereANY:
08020 t = error_mark_node;
08021 break;
08022 }
08023 break;
08024
08025 case FFEINFO_kindFUNCTION:
08026 switch (ffeinfo_where (ffesymbol_info (s)))
08027 {
08028 case FFEINFO_whereLOCAL:
08029 assert (!ffecom_transform_only_dummies_);
08030 t = current_function_decl;
08031 break;
08032
08033 case FFEINFO_whereGLOBAL:
08034 assert (!ffecom_transform_only_dummies_);
08035
08036 if (((g = ffesymbol_global (s)) != NULL)
08037 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
08038 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
08039 && (ffeglobal_hook (g) != NULL_TREE)
08040 && ffe_is_globals ())
08041 {
08042 t = ffeglobal_hook (g);
08043 break;
08044 }
08045
08046 if (ffesymbol_is_f2c (s)
08047 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
08048 t = ffecom_tree_fun_type[bt][kt];
08049 else
08050 t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE);
08051
08052 t = build_decl (FUNCTION_DECL,
08053 ffecom_get_external_identifier_ (s),
08054 t);
08055 DECL_EXTERNAL (t) = 1;
08056 TREE_PUBLIC (t) = 1;
08057
08058 t = start_decl (t, FALSE);
08059 finish_decl (t, NULL_TREE, FALSE);
08060
08061 if ((g != NULL)
08062 && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC)
08063 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
08064 ffeglobal_set_hook (g, t);
08065
08066 ffecom_save_tree_forever (t);
08067
08068 break;
08069
08070 case FFEINFO_whereDUMMY:
08071 assert (ffecom_transform_only_dummies_);
08072
08073 if (ffesymbol_is_f2c (s)
08074 && (ffesymbol_where (s) != FFEINFO_whereCONSTANT))
08075 t = ffecom_tree_ptr_to_fun_type[bt][kt];
08076 else
08077 t = build_pointer_type
08078 (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE));
08079
08080 t = build_decl (PARM_DECL,
08081 ffecom_get_identifier_ (ffesymbol_text (s)),
08082 t);
08083 DECL_ARTIFICIAL (t) = 1;
08084 addr = TRUE;
08085 break;
08086
08087 case FFEINFO_whereCONSTANT:
08088 assert (!ffecom_transform_only_dummies_);
08089 t = ffecom_gen_sfuncdef_ (s, bt, kt);
08090 break;
08091
08092 case FFEINFO_whereINTRINSIC:
08093 assert (!ffecom_transform_only_dummies_);
08094 break;
08095
08096
08097 default:
08098 assert ("FUNCTION where unheard of" == NULL);
08099
08100 case FFEINFO_whereANY:
08101 t = error_mark_node;
08102 break;
08103 }
08104 break;
08105
08106 case FFEINFO_kindSUBROUTINE:
08107 switch (ffeinfo_where (ffesymbol_info (s)))
08108 {
08109 case FFEINFO_whereLOCAL:
08110 assert (!ffecom_transform_only_dummies_);
08111 t = current_function_decl;
08112 break;
08113
08114 case FFEINFO_whereGLOBAL:
08115 assert (!ffecom_transform_only_dummies_);
08116
08117 if (((g = ffesymbol_global (s)) != NULL)
08118 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
08119 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))
08120 && (ffeglobal_hook (g) != NULL_TREE)
08121 && ffe_is_globals ())
08122 {
08123 t = ffeglobal_hook (g);
08124 break;
08125 }
08126
08127 t = build_decl (FUNCTION_DECL,
08128 ffecom_get_external_identifier_ (s),
08129 ffecom_tree_subr_type);
08130 DECL_EXTERNAL (t) = 1;
08131 TREE_PUBLIC (t) = 1;
08132
08133 t = start_decl (t, FALSE);
08134 finish_decl (t, NULL_TREE, FALSE);
08135
08136 if ((g != NULL)
08137 && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR)
08138 || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)))
08139 ffeglobal_set_hook (g, t);
08140
08141 ffecom_save_tree_forever (t);
08142
08143 break;
08144
08145 case FFEINFO_whereDUMMY:
08146 assert (ffecom_transform_only_dummies_);
08147
08148 t = build_decl (PARM_DECL,
08149 ffecom_get_identifier_ (ffesymbol_text (s)),
08150 ffecom_tree_ptr_to_subr_type);
08151 DECL_ARTIFICIAL (t) = 1;
08152 addr = TRUE;
08153 break;
08154
08155 case FFEINFO_whereINTRINSIC:
08156 assert (!ffecom_transform_only_dummies_);
08157 break;
08158
08159
08160 default:
08161 assert ("SUBROUTINE where unheard of" == NULL);
08162
08163 case FFEINFO_whereANY:
08164 t = error_mark_node;
08165 break;
08166 }
08167 break;
08168
08169 case FFEINFO_kindPROGRAM:
08170 switch (ffeinfo_where (ffesymbol_info (s)))
08171 {
08172 case FFEINFO_whereLOCAL:
08173 assert (!ffecom_transform_only_dummies_);
08174 t = current_function_decl;
08175 break;
08176
08177 case FFEINFO_whereCOMMON:
08178 case FFEINFO_whereDUMMY:
08179 case FFEINFO_whereGLOBAL:
08180 case FFEINFO_whereRESULT:
08181 case FFEINFO_whereFLEETING:
08182 case FFEINFO_whereFLEETING_CADDR:
08183 case FFEINFO_whereFLEETING_IADDR:
08184 case FFEINFO_whereIMMEDIATE:
08185 case FFEINFO_whereINTRINSIC:
08186 case FFEINFO_whereCONSTANT:
08187 case FFEINFO_whereCONSTANT_SUBOBJECT:
08188 default:
08189 assert ("PROGRAM where unheard of" == NULL);
08190
08191 case FFEINFO_whereANY:
08192 t = error_mark_node;
08193 break;
08194 }
08195 break;
08196
08197 case FFEINFO_kindBLOCKDATA:
08198 switch (ffeinfo_where (ffesymbol_info (s)))
08199 {
08200 case FFEINFO_whereLOCAL:
08201 assert (!ffecom_transform_only_dummies_);
08202 t = current_function_decl;
08203 break;
08204
08205 case FFEINFO_whereGLOBAL:
08206 assert (!ffecom_transform_only_dummies_);
08207
08208 t = build_decl (FUNCTION_DECL,
08209 ffecom_get_external_identifier_ (s),
08210 ffecom_tree_blockdata_type);
08211 DECL_EXTERNAL (t) = 1;
08212 TREE_PUBLIC (t) = 1;
08213
08214 t = start_decl (t, FALSE);
08215 finish_decl (t, NULL_TREE, FALSE);
08216
08217 ffecom_save_tree_forever (t);
08218
08219 break;
08220
08221 case FFEINFO_whereCOMMON:
08222 case FFEINFO_whereDUMMY:
08223 case FFEINFO_whereRESULT:
08224 case FFEINFO_whereFLEETING:
08225 case FFEINFO_whereFLEETING_CADDR:
08226 case FFEINFO_whereFLEETING_IADDR:
08227 case FFEINFO_whereIMMEDIATE:
08228 case FFEINFO_whereINTRINSIC:
08229 case FFEINFO_whereCONSTANT:
08230 case FFEINFO_whereCONSTANT_SUBOBJECT:
08231 default:
08232 assert ("BLOCKDATA where unheard of" == NULL);
08233
08234 case FFEINFO_whereANY:
08235 t = error_mark_node;
08236 break;
08237 }
08238 break;
08239
08240 case FFEINFO_kindCOMMON:
08241 switch (ffeinfo_where (ffesymbol_info (s)))
08242 {
08243 case FFEINFO_whereLOCAL:
08244 assert (!ffecom_transform_only_dummies_);
08245 ffecom_transform_common_ (s);
08246 break;
08247
08248 case FFEINFO_whereNONE:
08249 case FFEINFO_whereCOMMON:
08250 case FFEINFO_whereDUMMY:
08251 case FFEINFO_whereGLOBAL:
08252 case FFEINFO_whereRESULT:
08253 case FFEINFO_whereFLEETING:
08254 case FFEINFO_whereFLEETING_CADDR:
08255 case FFEINFO_whereFLEETING_IADDR:
08256 case FFEINFO_whereIMMEDIATE:
08257 case FFEINFO_whereINTRINSIC:
08258 case FFEINFO_whereCONSTANT:
08259 case FFEINFO_whereCONSTANT_SUBOBJECT:
08260 default:
08261 assert ("COMMON where unheard of" == NULL);
08262
08263 case FFEINFO_whereANY:
08264 t = error_mark_node;
08265 break;
08266 }
08267 break;
08268
08269 case FFEINFO_kindCONSTRUCT:
08270 switch (ffeinfo_where (ffesymbol_info (s)))
08271 {
08272 case FFEINFO_whereLOCAL:
08273 assert (!ffecom_transform_only_dummies_);
08274 break;
08275
08276 case FFEINFO_whereNONE:
08277 case FFEINFO_whereCOMMON:
08278 case FFEINFO_whereDUMMY:
08279 case FFEINFO_whereGLOBAL:
08280 case FFEINFO_whereRESULT:
08281 case FFEINFO_whereFLEETING:
08282 case FFEINFO_whereFLEETING_CADDR:
08283 case FFEINFO_whereFLEETING_IADDR:
08284 case FFEINFO_whereIMMEDIATE:
08285 case FFEINFO_whereINTRINSIC:
08286 case FFEINFO_whereCONSTANT:
08287 case FFEINFO_whereCONSTANT_SUBOBJECT:
08288 default:
08289 assert ("CONSTRUCT where unheard of" == NULL);
08290
08291 case FFEINFO_whereANY:
08292 t = error_mark_node;
08293 break;
08294 }
08295 break;
08296
08297 case FFEINFO_kindNAMELIST:
08298 switch (ffeinfo_where (ffesymbol_info (s)))
08299 {
08300 case FFEINFO_whereLOCAL:
08301 assert (!ffecom_transform_only_dummies_);
08302 t = ffecom_transform_namelist_ (s);
08303 break;
08304
08305 case FFEINFO_whereNONE:
08306 case FFEINFO_whereCOMMON:
08307 case FFEINFO_whereDUMMY:
08308 case FFEINFO_whereGLOBAL:
08309 case FFEINFO_whereRESULT:
08310 case FFEINFO_whereFLEETING:
08311 case FFEINFO_whereFLEETING_CADDR:
08312 case FFEINFO_whereFLEETING_IADDR:
08313 case FFEINFO_whereIMMEDIATE:
08314 case FFEINFO_whereINTRINSIC:
08315 case FFEINFO_whereCONSTANT:
08316 case FFEINFO_whereCONSTANT_SUBOBJECT:
08317 default:
08318 assert ("NAMELIST where unheard of" == NULL);
08319
08320 case FFEINFO_whereANY:
08321 t = error_mark_node;
08322 break;
08323 }
08324 break;
08325
08326 default:
08327 assert ("kind unheard of" == NULL);
08328
08329 case FFEINFO_kindANY:
08330 t = error_mark_node;
08331 break;
08332 }
08333
08334 ffesymbol_hook (s).decl_tree = t;
08335 ffesymbol_hook (s).length_tree = tlen;
08336 ffesymbol_hook (s).addr = addr;
08337
08338 lineno = old_lineno;
08339 input_filename = old_input_filename;
08340
08341 return s;
08342 }
08343
08344
08345
08346
08347
08348
08349
08350
08351
08352 static ffesymbol
08353 ffecom_sym_transform_assign_ (ffesymbol s)
08354 {
08355 tree t;
08356 int old_lineno = lineno;
08357 const char *old_input_filename = input_filename;
08358
08359 if (ffesymbol_sfdummyparent (s) == NULL)
08360 {
08361 input_filename = ffesymbol_where_filename (s);
08362 lineno = ffesymbol_where_filelinenum (s);
08363 }
08364 else
08365 {
08366 ffesymbol sf = ffesymbol_sfdummyparent (s);
08367
08368 input_filename = ffesymbol_where_filename (sf);
08369 lineno = ffesymbol_where_filelinenum (sf);
08370 }
08371
08372 assert (!ffecom_transform_only_dummies_);
08373
08374 t = build_decl (VAR_DECL,
08375 ffecom_get_invented_identifier ("__g77_ASSIGN_%s",
08376 ffesymbol_text (s)),
08377 TREE_TYPE (null_pointer_node));
08378
08379 switch (ffesymbol_where (s))
08380 {
08381 case FFEINFO_whereLOCAL:
08382
08383
08384
08385
08386
08387 if ((ffesymbol_is_save (s) || ffe_is_saveall ())
08388 && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
08389 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA))
08390 TREE_STATIC (t) = 1;
08391 else
08392 TREE_STATIC (t) = 0;
08393 break;
08394
08395 case FFEINFO_whereCOMMON:
08396 TREE_STATIC (t) = 1;
08397 break;
08398
08399 case FFEINFO_whereDUMMY:
08400
08401
08402
08403
08404
08405
08406 TREE_STATIC (t) = 0;
08407 break;
08408
08409 default:
08410 TREE_STATIC (t) = 0;
08411 break;
08412 }
08413
08414 t = start_decl (t, FALSE);
08415 finish_decl (t, NULL_TREE, FALSE);
08416
08417 ffesymbol_hook (s).assign_tree = t;
08418
08419 lineno = old_lineno;
08420 input_filename = old_input_filename;
08421
08422 return s;
08423 }
08424
08425
08426
08427
08428
08429
08430
08431
08432
08433
08434
08435
08436
08437
08438
08439
08440
08441
08442
08443
08444
08445
08446
08447
08448
08449
08450
08451
08452
08453 static void
08454 ffecom_transform_common_ (ffesymbol s)
08455 {
08456 ffestorag st = ffesymbol_storage (s);
08457 ffeglobal g = ffesymbol_global (s);
08458 tree cbt;
08459 tree cbtype;
08460 tree init;
08461 tree high;
08462 bool is_init = ffestorag_is_init (st);
08463
08464 assert (st != NULL);
08465
08466 if ((g == NULL)
08467 || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON))
08468 return;
08469
08470
08471
08472 ffeglobal_size_common (s, ffestorag_size (st));
08473
08474 if (!ffeglobal_common_init (g))
08475 is_init = FALSE;
08476
08477 cbt = ffeglobal_hook (g);
08478
08479
08480
08481
08482
08483 if ((cbt != NULL_TREE)
08484 && (!is_init
08485 || !DECL_EXTERNAL (cbt)))
08486 {
08487 if (st->hook == NULL) ffestorag_set_hook (st, cbt);
08488 return;
08489 }
08490
08491
08492
08493 if (is_init)
08494 {
08495 if (ffestorag_init (st) != NULL)
08496 {
08497 ffebld sexp;
08498
08499
08500
08501 switch (ffebld_op (sexp = ffestorag_init (st)))
08502 {
08503 case FFEBLD_opCONTER:
08504 ffebld_conter_set_pad (sexp, ffestorag_modulo (st));
08505 break;
08506
08507 case FFEBLD_opARRTER:
08508 ffebld_arrter_set_pad (sexp, ffestorag_modulo (st));
08509 break;
08510
08511 case FFEBLD_opACCTER:
08512 ffebld_accter_set_pad (sexp, ffestorag_modulo (st));
08513 break;
08514
08515 default:
08516 assert ("bad op for cmn init (pad)" == NULL);
08517 break;
08518 }
08519
08520 init = ffecom_expr (sexp);
08521 if (init == error_mark_node)
08522 {
08523 init = NULL_TREE;
08524 if (cbt != NULL_TREE)
08525 return;
08526 }
08527 }
08528 else
08529 init = error_mark_node;
08530 }
08531 else
08532 init = NULL_TREE;
08533
08534
08535
08536
08537 high = build_int_2 ((ffeglobal_common_size (g)
08538 + ffeglobal_common_pad (g)) - 1, 0);
08539 TREE_TYPE (high) = ffecom_integer_type_node;
08540
08541 if (init)
08542 cbtype = build_array_type (char_type_node,
08543 build_range_type (integer_type_node,
08544 integer_zero_node,
08545 high));
08546 else
08547 cbtype = build_array_type (char_type_node, NULL_TREE);
08548
08549 if (cbt == NULL_TREE)
08550 {
08551 cbt
08552 = build_decl (VAR_DECL,
08553 ffecom_get_external_identifier_ (s),
08554 cbtype);
08555 TREE_STATIC (cbt) = 1;
08556 TREE_PUBLIC (cbt) = 1;
08557 }
08558 else
08559 {
08560 assert (is_init);
08561 TREE_TYPE (cbt) = cbtype;
08562 }
08563 DECL_EXTERNAL (cbt) = init ? 0 : 1;
08564 DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE;
08565
08566 cbt = start_decl (cbt, TRUE);
08567 if (ffeglobal_hook (g) != NULL)
08568 assert (cbt == ffeglobal_hook (g));
08569
08570 assert (!init || !DECL_EXTERNAL (cbt));
08571
08572
08573
08574
08575
08576
08577 DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT;
08578 DECL_USER_ALIGN (cbt) = 0;
08579
08580 if (is_init && (ffestorag_init (st) == NULL))
08581 init = ffecom_init_zero_ (cbt);
08582
08583 finish_decl (cbt, init, TRUE);
08584
08585 if (is_init)
08586 ffestorag_set_init (st, ffebld_new_any ());
08587
08588 if (init)
08589 {
08590 assert (DECL_SIZE_UNIT (cbt) != NULL_TREE);
08591 assert (TREE_CODE (DECL_SIZE_UNIT (cbt)) == INTEGER_CST);
08592 assert (0 == compare_tree_int (DECL_SIZE_UNIT (cbt),
08593 (ffeglobal_common_size (g)
08594 + ffeglobal_common_pad (g))));
08595 }
08596
08597 ffeglobal_set_hook (g, cbt);
08598
08599 ffestorag_set_hook (st, cbt);
08600
08601 ffecom_save_tree_forever (cbt);
08602 }
08603
08604
08605
08606 static void
08607 ffecom_transform_equiv_ (ffestorag eqst)
08608 {
08609 tree eqt;
08610 tree eqtype;
08611 tree init;
08612 tree high;
08613 bool is_init = ffestorag_is_init (eqst);
08614
08615 assert (eqst != NULL);
08616
08617 eqt = ffestorag_hook (eqst);
08618
08619 if (eqt != NULL_TREE)
08620 return;
08621
08622
08623
08624 if (is_init)
08625 {
08626 if (ffestorag_init (eqst) != NULL)
08627 {
08628 ffebld sexp;
08629
08630
08631
08632 switch (ffebld_op (sexp = ffestorag_init (eqst)))
08633 {
08634 case FFEBLD_opCONTER:
08635 ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst));
08636 break;
08637
08638 case FFEBLD_opARRTER:
08639 ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst));
08640 break;
08641
08642 case FFEBLD_opACCTER:
08643 ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst));
08644 break;
08645
08646 default:
08647 assert ("bad op for eqv init (pad)" == NULL);
08648 break;
08649 }
08650
08651 init = ffecom_expr (sexp);
08652 if (init == error_mark_node)
08653 init = NULL_TREE;
08654 }
08655 else
08656 init = error_mark_node;
08657 }
08658 else if (ffe_is_init_local_zero ())
08659 init = error_mark_node;
08660 else
08661 init = NULL_TREE;
08662
08663 ffecom_member_namelisted_ = FALSE;
08664 ffestorag_drive (ffestorag_list_equivs (eqst),
08665 &ffecom_member_phase1_,
08666 eqst);
08667
08668 high = build_int_2 ((ffestorag_size (eqst)
08669 + ffestorag_modulo (eqst)) - 1, 0);
08670 TREE_TYPE (high) = ffecom_integer_type_node;
08671
08672 eqtype = build_array_type (char_type_node,
08673 build_range_type (ffecom_integer_type_node,
08674 ffecom_integer_zero_node,
08675 high));
08676
08677 eqt = build_decl (VAR_DECL,
08678 ffecom_get_invented_identifier ("__g77_equiv_%s",
08679 ffesymbol_text
08680 (ffestorag_symbol (eqst))),
08681 eqtype);
08682 DECL_EXTERNAL (eqt) = 0;
08683 if (is_init
08684 || ffecom_member_namelisted_
08685 #ifdef FFECOM_sizeMAXSTACKITEM
08686 || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM)
08687 #endif
08688 || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM)
08689 && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)
08690 && (ffestorag_is_save (eqst) || ffe_is_saveall ())))
08691 TREE_STATIC (eqt) = 1;
08692 else
08693 TREE_STATIC (eqt) = 0;
08694 TREE_PUBLIC (eqt) = 0;
08695 TREE_ADDRESSABLE (eqt) = 1;
08696 DECL_CONTEXT (eqt) = current_function_decl;
08697 if (init)
08698 DECL_INITIAL (eqt) = error_mark_node;
08699 else
08700 DECL_INITIAL (eqt) = NULL_TREE;
08701
08702 eqt = start_decl (eqt, FALSE);
08703
08704
08705
08706
08707
08708
08709 DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT;
08710 DECL_USER_ALIGN (eqt) = 0;
08711
08712 if ((!is_init && ffe_is_init_local_zero ())
08713 || (is_init && (ffestorag_init (eqst) == NULL)))
08714 init = ffecom_init_zero_ (eqt);
08715
08716 finish_decl (eqt, init, FALSE);
08717
08718 if (is_init)
08719 ffestorag_set_init (eqst, ffebld_new_any ());
08720
08721 {
08722 assert (TREE_CODE (DECL_SIZE_UNIT (eqt)) == INTEGER_CST);
08723 assert (0 == compare_tree_int (DECL_SIZE_UNIT (eqt),
08724 (ffestorag_size (eqst)
08725 + ffestorag_modulo (eqst))));
08726 }
08727
08728 ffestorag_set_hook (eqst, eqt);
08729
08730 ffestorag_drive (ffestorag_list_equivs (eqst),
08731 &ffecom_member_phase2_,
08732 eqst);
08733 }
08734
08735
08736
08737 static tree
08738 ffecom_transform_namelist_ (ffesymbol s)
08739 {
08740 tree nmlt;
08741 tree nmltype = ffecom_type_namelist_ ();
08742 tree nmlinits;
08743 tree nameinit;
08744 tree varsinit;
08745 tree nvarsinit;
08746 tree field;
08747 tree high;
08748 int i;
08749 static int mynumber = 0;
08750
08751 nmlt = build_decl (VAR_DECL,
08752 ffecom_get_invented_identifier ("__g77_namelist_%d",
08753 mynumber++),
08754 nmltype);
08755 TREE_STATIC (nmlt) = 1;
08756 DECL_INITIAL (nmlt) = error_mark_node;
08757
08758 nmlt = start_decl (nmlt, FALSE);
08759
08760
08761
08762 i = strlen (ffesymbol_text (s));
08763
08764 high = build_int_2 (i, 0);
08765 TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node;
08766
08767 nameinit = ffecom_build_f2c_string_ (i + 1,
08768 ffesymbol_text (s));
08769 TREE_TYPE (nameinit)
08770 = build_type_variant
08771 (build_array_type
08772 (char_type_node,
08773 build_range_type (ffecom_f2c_ftnlen_type_node,
08774 ffecom_f2c_ftnlen_one_node,
08775 high)),
08776 1, 0);
08777 TREE_CONSTANT (nameinit) = 1;
08778 TREE_STATIC (nameinit) = 1;
08779 nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)),
08780 nameinit);
08781
08782 varsinit = ffecom_vardesc_array_ (s);
08783 varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)),
08784 varsinit);
08785 TREE_CONSTANT (varsinit) = 1;
08786 TREE_STATIC (varsinit) = 1;
08787
08788 {
08789 ffebld b;
08790
08791 for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b))
08792 ++i;
08793 }
08794 nvarsinit = build_int_2 (i, 0);
08795 TREE_TYPE (nvarsinit) = integer_type_node;
08796 TREE_CONSTANT (nvarsinit) = 1;
08797 TREE_STATIC (nvarsinit) = 1;
08798
08799 nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit);
08800 TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)),
08801 varsinit);
08802 TREE_CHAIN (TREE_CHAIN (nmlinits))
08803 = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
08804
08805 nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
08806 TREE_CONSTANT (nmlinits) = 1;
08807 TREE_STATIC (nmlinits) = 1;
08808
08809 finish_decl (nmlt, nmlinits, FALSE);
08810
08811 nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt);
08812
08813 return nmlt;
08814 }
08815
08816
08817
08818
08819
08820
08821 static void
08822 ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
08823 tree t)
08824 {
08825 switch (TREE_CODE (t))
08826 {
08827 case NOP_EXPR:
08828 case CONVERT_EXPR:
08829 case NON_LVALUE_EXPR:
08830 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
08831 break;
08832
08833 case PLUS_EXPR:
08834 ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0));
08835 if ((*decl == NULL_TREE)
08836 || (*decl == error_mark_node))
08837 break;
08838
08839 if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
08840 {
08841
08842 *offset = fold (build (PLUS_EXPR, TREE_TYPE (*offset),
08843 *offset, TREE_OPERAND (t, 1)));
08844
08845
08846 *offset = size_binop (MULT_EXPR,
08847 convert (bitsizetype, *offset),
08848 TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))));
08849 break;
08850 }
08851
08852 *decl = error_mark_node;
08853 break;
08854
08855 case PARM_DECL:
08856 *decl = t;
08857 *offset = bitsize_zero_node;
08858 break;
08859
08860 case ADDR_EXPR:
08861 if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL)
08862 {
08863
08864 *decl = TREE_OPERAND (t, 0);
08865 *offset = bitsize_zero_node;
08866 break;
08867 }
08868
08869 default:
08870
08871 *decl = error_mark_node;
08872 break;
08873 }
08874 }
08875
08876
08877
08878
08879
08880
08881
08882
08883
08884
08885
08886
08887
08888
08889
08890
08891
08892
08893
08894
08895
08896
08897
08898
08899
08900
08901
08902
08903
08904
08905
08906
08907 static void
08908 ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
08909 tree *size, tree t)
08910 {
08911
08912 *decl = NULL_TREE;
08913
08914 if (t == NULL_TREE)
08915 return;
08916
08917 switch (TREE_CODE (t))
08918 {
08919 case ERROR_MARK:
08920 case IDENTIFIER_NODE:
08921 case INTEGER_CST:
08922 case REAL_CST:
08923 case COMPLEX_CST:
08924 case STRING_CST:
08925 case CONST_DECL:
08926 case PLUS_EXPR:
08927 case MINUS_EXPR:
08928 case MULT_EXPR:
08929 case TRUNC_DIV_EXPR:
08930 case CEIL_DIV_EXPR:
08931 case FLOOR_DIV_EXPR:
08932 case ROUND_DIV_EXPR:
08933 case TRUNC_MOD_EXPR:
08934 case CEIL_MOD_EXPR:
08935 case FLOOR_MOD_EXPR:
08936 case ROUND_MOD_EXPR:
08937 case RDIV_EXPR:
08938 case EXACT_DIV_EXPR:
08939 case FIX_TRUNC_EXPR:
08940 case FIX_CEIL_EXPR:
08941 case FIX_FLOOR_EXPR:
08942 case FIX_ROUND_EXPR:
08943 case FLOAT_EXPR:
08944 case NEGATE_EXPR:
08945 case MIN_EXPR:
08946 case MAX_EXPR:
08947 case ABS_EXPR:
08948 case FFS_EXPR:
08949 case LSHIFT_EXPR:
08950 case RSHIFT_EXPR:
08951 case LROTATE_EXPR:
08952 case RROTATE_EXPR:
08953 case BIT_IOR_EXPR:
08954 case BIT_XOR_EXPR:
08955 case BIT_AND_EXPR:
08956 case BIT_ANDTC_EXPR:
08957 case BIT_NOT_EXPR:
08958 case TRUTH_ANDIF_EXPR:
08959 case TRUTH_ORIF_EXPR:
08960 case TRUTH_AND_EXPR:
08961 case TRUTH_OR_EXPR:
08962 case TRUTH_XOR_EXPR:
08963 case TRUTH_NOT_EXPR:
08964 case LT_EXPR:
08965 case LE_EXPR:
08966 case GT_EXPR:
08967 case GE_EXPR:
08968 case EQ_EXPR:
08969 case NE_EXPR:
08970 case COMPLEX_EXPR:
08971 case CONJ_EXPR:
08972 case REALPART_EXPR:
08973 case IMAGPART_EXPR:
08974 case LABEL_EXPR:
08975 case COMPONENT_REF:
08976 case COMPOUND_EXPR:
08977 case ADDR_EXPR:
08978 return;
08979
08980 case VAR_DECL:
08981 case PARM_DECL:
08982 *decl = t;
08983 *offset = bitsize_zero_node;
08984 *size = TYPE_SIZE (TREE_TYPE (t));
08985 return;
08986
08987 case ARRAY_REF:
08988 {
08989 tree array = TREE_OPERAND (t, 0);
08990 tree element = TREE_OPERAND (t, 1);
08991 tree init_offset;
08992
08993 if ((array == NULL_TREE)
08994 || (element == NULL_TREE))
08995 {
08996 *decl = error_mark_node;
08997 return;
08998 }
08999
09000 ffecom_tree_canonize_ref_ (decl, &init_offset, size,
09001 array);
09002 if ((*decl == NULL_TREE)
09003 || (*decl == error_mark_node))
09004 return;
09005
09006
09007 *offset = fold (build (MINUS_EXPR, TREE_TYPE (element),
09008 element,
09009 TYPE_MIN_VALUE (TYPE_DOMAIN
09010 (TREE_TYPE (array)))));
09011
09012 *offset = size_binop (MULT_EXPR,
09013 convert (bitsizetype, *offset),
09014 TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))));
09015
09016 *offset = size_binop (PLUS_EXPR, init_offset, *offset);
09017
09018 *size = TYPE_SIZE (TREE_TYPE (t));
09019 return;
09020 }
09021
09022 case INDIRECT_REF:
09023
09024
09025
09026
09027
09028
09029
09030
09031
09032 *size = TYPE_SIZE (TREE_TYPE (t));
09033
09034 ffecom_tree_canonize_ptr_ (decl, offset,
09035 TREE_OPERAND (t, 0));
09036
09037 return;
09038
09039 case CONVERT_EXPR:
09040 case NOP_EXPR:
09041 case MODIFY_EXPR:
09042 case NON_LVALUE_EXPR:
09043 case RESULT_DECL:
09044 case FIELD_DECL:
09045 case COND_EXPR:
09046 case SAVE_EXPR:
09047 case REFERENCE_EXPR:
09048 case PREDECREMENT_EXPR:
09049 case PREINCREMENT_EXPR:
09050 case POSTDECREMENT_EXPR:
09051 case POSTINCREMENT_EXPR:
09052 case CALL_EXPR:
09053 default:
09054 *decl = error_mark_node;
09055 return;
09056 }
09057 }
09058
09059
09060
09061 static tree
09062 ffecom_tree_divide_ (tree tree_type, tree left, tree right,
09063 tree dest_tree, ffebld dest, bool *dest_used,
09064 tree hook)
09065 {
09066 if ((left == error_mark_node)
09067 || (right == error_mark_node))
09068 return error_mark_node;
09069
09070 switch (TREE_CODE (tree_type))
09071 {
09072 case INTEGER_TYPE:
09073 return ffecom_2 (TRUNC_DIV_EXPR, tree_type,
09074 left,
09075 right);
09076
09077 case COMPLEX_TYPE:
09078 if (! optimize_size)
09079 return ffecom_2 (RDIV_EXPR, tree_type,
09080 left,
09081 right);
09082 {
09083 ffecomGfrt ix;
09084
09085 if (TREE_TYPE (tree_type)
09086 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
09087 ix = FFECOM_gfrtDIV_CC;
09088 else
09089 ix = FFECOM_gfrtDIV_ZZ;
09090
09091 left = ffecom_1 (ADDR_EXPR,
09092 build_pointer_type (TREE_TYPE (left)),
09093 left);
09094 left = build_tree_list (NULL_TREE, left);
09095 right = ffecom_1 (ADDR_EXPR,
09096 build_pointer_type (TREE_TYPE (right)),
09097 right);
09098 right = build_tree_list (NULL_TREE, right);
09099 TREE_CHAIN (left) = right;
09100
09101 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
09102 ffecom_gfrt_kindtype (ix),
09103 ffe_is_f2c_library (),
09104 tree_type,
09105 left,
09106 dest_tree, dest, dest_used,
09107 NULL_TREE, TRUE, hook);
09108 }
09109 break;
09110
09111 case RECORD_TYPE:
09112 {
09113 ffecomGfrt ix;
09114
09115 if (TREE_TYPE (TYPE_FIELDS (tree_type))
09116 == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1])
09117 ix = FFECOM_gfrtDIV_CC;
09118 else
09119 ix = FFECOM_gfrtDIV_ZZ;
09120
09121 left = ffecom_1 (ADDR_EXPR,
09122 build_pointer_type (TREE_TYPE (left)),
09123 left);
09124 left = build_tree_list (NULL_TREE, left);
09125 right = ffecom_1 (ADDR_EXPR,
09126 build_pointer_type (TREE_TYPE (right)),
09127 right);
09128 right = build_tree_list (NULL_TREE, right);
09129 TREE_CHAIN (left) = right;
09130
09131 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
09132 ffecom_gfrt_kindtype (ix),
09133 ffe_is_f2c_library (),
09134 tree_type,
09135 left,
09136 dest_tree, dest, dest_used,
09137 NULL_TREE, TRUE, hook);
09138 }
09139 break;
09140
09141 default:
09142 return ffecom_2 (RDIV_EXPR, tree_type,
09143 left,
09144 right);
09145 }
09146 }
09147
09148
09149
09150 static tree
09151 ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
09152 ffeinfoKindtype kt)
09153 {
09154 tree type;
09155 ffebld dl;
09156 ffebld dim;
09157 tree lowt;
09158 tree hight;
09159
09160 type = ffecom_tree_type[bt][kt];
09161 if (bt == FFEINFO_basictypeCHARACTER)
09162 {
09163 hight = build_int_2 (ffesymbol_size (s), 0);
09164 TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node;
09165
09166 type
09167 = build_array_type
09168 (type,
09169 build_range_type (ffecom_f2c_ftnlen_type_node,
09170 ffecom_f2c_ftnlen_one_node,
09171 hight));
09172 type = ffecom_check_size_overflow_ (s, type, FALSE);
09173 }
09174
09175 for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl))
09176 {
09177 if (type == error_mark_node)
09178 break;
09179
09180 dim = ffebld_head (dl);
09181 assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
09182
09183 if (ffebld_left (dim) == NULL)
09184 lowt = integer_one_node;
09185 else
09186 lowt = ffecom_expr (ffebld_left (dim));
09187
09188 if (TREE_CODE (lowt) != INTEGER_CST)
09189 lowt = variable_size (lowt);
09190
09191 assert (ffebld_right (dim) != NULL);
09192 hight = ffecom_expr (ffebld_right (dim));
09193
09194 if (TREE_CODE (hight) != INTEGER_CST)
09195 hight = variable_size (hight);
09196
09197 type = build_array_type (type,
09198 build_range_type (ffecom_integer_type_node,
09199 lowt, hight));
09200 type = ffecom_check_size_overflow_ (s, type, FALSE);
09201 }
09202
09203 return type;
09204 }
09205
09206
09207
09208 static tree
09209 ffecom_type_namelist_ ()
09210 {
09211 static tree type = NULL_TREE;
09212
09213 if (type == NULL_TREE)
09214 {
09215 static tree namefield, varsfield, nvarsfield;
09216 tree vardesctype;
09217
09218 vardesctype = ffecom_type_vardesc_ ();
09219
09220 type = make_node (RECORD_TYPE);
09221
09222 vardesctype = build_pointer_type (build_pointer_type (vardesctype));
09223
09224 namefield = ffecom_decl_field (type, NULL_TREE, "name",
09225 string_type_node);
09226 varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype);
09227 nvarsfield = ffecom_decl_field (type, varsfield, "nvars",
09228 integer_type_node);
09229
09230 TYPE_FIELDS (type) = namefield;
09231 layout_type (type);
09232
09233 ggc_add_tree_root (&type, 1);
09234 }
09235
09236 return type;
09237 }
09238
09239
09240
09241 static tree
09242 ffecom_type_vardesc_ ()
09243 {
09244 static tree type = NULL_TREE;
09245 static tree namefield, addrfield, dimsfield, typefield;
09246
09247 if (type == NULL_TREE)
09248 {
09249 type = make_node (RECORD_TYPE);
09250
09251 namefield = ffecom_decl_field (type, NULL_TREE, "name",
09252 string_type_node);
09253 addrfield = ffecom_decl_field (type, namefield, "addr",
09254 string_type_node);
09255 dimsfield = ffecom_decl_field (type, addrfield, "dims",
09256 ffecom_f2c_ptr_to_ftnlen_type_node);
09257 typefield = ffecom_decl_field (type, dimsfield, "type",
09258 integer_type_node);
09259
09260 TYPE_FIELDS (type) = namefield;
09261 layout_type (type);
09262
09263 ggc_add_tree_root (&type, 1);
09264 }
09265
09266 return type;
09267 }
09268
09269 static tree
09270 ffecom_vardesc_ (ffebld expr)
09271 {
09272 ffesymbol s;
09273
09274 assert (ffebld_op (expr) == FFEBLD_opSYMTER);
09275 s = ffebld_symter (expr);
09276
09277 if (ffesymbol_hook (s).vardesc_tree == NULL_TREE)
09278 {
09279 int i;
09280 tree vardesctype = ffecom_type_vardesc_ ();
09281 tree var;
09282 tree nameinit;
09283 tree dimsinit;
09284 tree addrinit;
09285 tree typeinit;
09286 tree field;
09287 tree varinits;
09288 static int mynumber = 0;
09289
09290 var = build_decl (VAR_DECL,
09291 ffecom_get_invented_identifier ("__g77_vardesc_%d",
09292 mynumber++),
09293 vardesctype);
09294 TREE_STATIC (var) = 1;
09295 DECL_INITIAL (var) = error_mark_node;
09296
09297 var = start_decl (var, FALSE);
09298
09299
09300
09301 nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s)))
09302 + 1,
09303 ffesymbol_text (s));
09304 TREE_TYPE (nameinit)
09305 = build_type_variant
09306 (build_array_type
09307 (char_type_node,
09308 build_range_type (integer_type_node,
09309 integer_one_node,
09310 build_int_2 (i, 0))),
09311 1, 0);
09312 TREE_CONSTANT (nameinit) = 1;
09313 TREE_STATIC (nameinit) = 1;
09314 nameinit = ffecom_1 (ADDR_EXPR,
09315 build_pointer_type (TREE_TYPE (nameinit)),
09316 nameinit);
09317
09318 addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit);
09319
09320 dimsinit = ffecom_vardesc_dims_ (s);
09321
09322 if (typeinit == NULL_TREE)
09323 {
09324 ffeinfoBasictype bt = ffesymbol_basictype (s);
09325 ffeinfoKindtype kt = ffesymbol_kindtype (s);
09326 int tc = ffecom_f2c_typecode (bt, kt);
09327
09328 assert (tc != -1);
09329 typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0);
09330 }
09331 else
09332 typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit);
09333
09334 varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)),
09335 nameinit);
09336 TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)),
09337 addrinit);
09338 TREE_CHAIN (TREE_CHAIN (varinits))
09339 = build_tree_list ((field = TREE_CHAIN (field)), dimsinit);
09340 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
09341 = build_tree_list ((field = TREE_CHAIN (field)), typeinit);
09342
09343 varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
09344 TREE_CONSTANT (varinits) = 1;
09345 TREE_STATIC (varinits) = 1;
09346
09347 finish_decl (var, varinits, FALSE);
09348
09349 var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var);
09350
09351 ffesymbol_hook (s).vardesc_tree = var;
09352 }
09353
09354 return ffesymbol_hook (s).vardesc_tree;
09355 }
09356
09357 static tree
09358 ffecom_vardesc_array_ (ffesymbol s)
09359 {
09360 ffebld b;
09361 tree list;
09362 tree item = NULL_TREE;
09363 tree var;
09364 int i;
09365 static int mynumber = 0;
09366
09367 for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s);
09368 b != NULL;
09369 b = ffebld_trail (b), ++i)
09370 {
09371 tree t;
09372
09373 t = ffecom_vardesc_ (ffebld_head (b));
09374
09375 if (list == NULL_TREE)
09376 list = item = build_tree_list (NULL_TREE, t);
09377 else
09378 {
09379 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
09380 item = TREE_CHAIN (item);
09381 }
09382 }
09383
09384 item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()),
09385 build_range_type (integer_type_node,
09386 integer_one_node,
09387 build_int_2 (i, 0)));
09388 list = build (CONSTRUCTOR, item, NULL_TREE, list);
09389 TREE_CONSTANT (list) = 1;
09390 TREE_STATIC (list) = 1;
09391
09392 var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", mynumber++);
09393 var = build_decl (VAR_DECL, var, item);
09394 TREE_STATIC (var) = 1;
09395 DECL_INITIAL (var) = error_mark_node;
09396 var = start_decl (var, FALSE);
09397 finish_decl (var, list, FALSE);
09398
09399 return var;
09400 }
09401
09402 static tree
09403 ffecom_vardesc_dims_ (ffesymbol s)
09404 {
09405 if (ffesymbol_dims (s) == NULL)
09406 return convert (ffecom_f2c_ptr_to_ftnlen_type_node,
09407 integer_zero_node);
09408
09409 {
09410 ffebld b;
09411 ffebld e;
09412 tree list;
09413 tree backlist;
09414 tree item = NULL_TREE;
09415 tree var;
09416 tree numdim;
09417 tree numelem;
09418 tree baseoff = NULL_TREE;
09419 static int mynumber = 0;
09420
09421 numdim = build_int_2 ((int) ffesymbol_rank (s), 0);
09422 TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node;
09423
09424 numelem = ffecom_expr (ffesymbol_arraysize (s));
09425 TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node;
09426
09427 list = NULL_TREE;
09428 backlist = NULL_TREE;
09429 for (b = ffesymbol_dims (s), e = ffesymbol_extents (s);
09430 b != NULL;
09431 b = ffebld_trail (b), e = ffebld_trail (e))
09432 {
09433 tree t;
09434 tree low;
09435 tree back;
09436
09437 if (ffebld_trail (b) == NULL)
09438 t = NULL_TREE;
09439 else
09440 {
09441 t = convert (ffecom_f2c_ftnlen_type_node,
09442 ffecom_expr (ffebld_head (e)));
09443
09444 if (list == NULL_TREE)
09445 list = item = build_tree_list (NULL_TREE, t);
09446 else
09447 {
09448 TREE_CHAIN (item) = build_tree_list (NULL_TREE, t);
09449 item = TREE_CHAIN (item);
09450 }
09451 }
09452
09453 if (ffebld_left (ffebld_head (b)) == NULL)
09454 low = ffecom_integer_one_node;
09455 else
09456 low = ffecom_expr (ffebld_left (ffebld_head (b)));
09457 low = convert (ffecom_f2c_ftnlen_type_node, low);
09458
09459 back = build_tree_list (low, t);
09460 TREE_CHAIN (back) = backlist;
09461 backlist = back;
09462 }
09463
09464 for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item))
09465 {
09466 if (TREE_VALUE (item) == NULL_TREE)
09467 baseoff = TREE_PURPOSE (item);
09468 else
09469 baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
09470 TREE_PURPOSE (item),
09471 ffecom_2 (MULT_EXPR,
09472 ffecom_f2c_ftnlen_type_node,
09473 TREE_VALUE (item),
09474 baseoff));
09475 }
09476
09477
09478
09479 baseoff = build_tree_list (NULL_TREE, baseoff);
09480 TREE_CHAIN (baseoff) = list;
09481
09482 numelem = build_tree_list (NULL_TREE, numelem);
09483 TREE_CHAIN (numelem) = baseoff;
09484
09485 numdim = build_tree_list (NULL_TREE, numdim);
09486 TREE_CHAIN (numdim) = numelem;
09487
09488 item = build_array_type (ffecom_f2c_ftnlen_type_node,
09489 build_range_type (integer_type_node,
09490 integer_zero_node,
09491 build_int_2
09492 ((int) ffesymbol_rank (s)
09493 + 2, 0)));
09494 list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
09495 TREE_CONSTANT (list) = 1;
09496 TREE_STATIC (list) = 1;
09497
09498 var = ffecom_get_invented_identifier ("__g77_dims_%d", mynumber++);
09499 var = build_decl (VAR_DECL, var, item);
09500 TREE_STATIC (var) = 1;
09501 DECL_INITIAL (var) = error_mark_node;
09502 var = start_decl (var, FALSE);
09503 finish_decl (var, list, FALSE);
09504
09505 var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var);
09506
09507 return var;
09508 }
09509 }
09510
09511
09512
09513
09514
09515
09516
09517 tree
09518 ffecom_1 (enum tree_code code, tree type, tree node)
09519 {
09520 tree item;
09521
09522 if ((node == error_mark_node)
09523 || (type == error_mark_node))
09524 return error_mark_node;
09525
09526 if (code == ADDR_EXPR)
09527 {
09528 if (!mark_addressable (node))
09529 assert ("can't mark_addressable this node!" == NULL);
09530 }
09531
09532 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
09533 {
09534 tree realtype;
09535
09536 case REALPART_EXPR:
09537 item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node)));
09538 break;
09539
09540 case IMAGPART_EXPR:
09541 item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node))));
09542 break;
09543
09544
09545 case NEGATE_EXPR:
09546 if (TREE_CODE (type) != RECORD_TYPE)
09547 {
09548 item = build1 (code, type, node);
09549 break;
09550 }
09551 node = ffecom_stabilize_aggregate_ (node);
09552 realtype = TREE_TYPE (TYPE_FIELDS (type));
09553 item =
09554 ffecom_2 (COMPLEX_EXPR, type,
09555 ffecom_1 (NEGATE_EXPR, realtype,
09556 ffecom_1 (REALPART_EXPR, realtype,
09557 node)),
09558 ffecom_1 (NEGATE_EXPR, realtype,
09559 ffecom_1 (IMAGPART_EXPR, realtype,
09560 node)));
09561 break;
09562
09563 default:
09564 item = build1 (code, type, node);
09565 break;
09566 }
09567
09568 if (TREE_SIDE_EFFECTS (node))
09569 TREE_SIDE_EFFECTS (item) = 1;
09570 if (code == ADDR_EXPR && staticp (node))
09571 TREE_CONSTANT (item) = 1;
09572 else if (code == INDIRECT_REF)
09573 TREE_READONLY (item) = TYPE_READONLY (type);
09574 return fold (item);
09575 }
09576
09577
09578
09579
09580
09581
09582
09583 tree
09584 ffecom_1_fn (tree node)
09585 {
09586 tree item;
09587 tree type;
09588
09589 if (node == error_mark_node)
09590 return error_mark_node;
09591
09592 type = build_type_variant (TREE_TYPE (node),
09593 TREE_READONLY (node),
09594 TREE_THIS_VOLATILE (node));
09595 item = build1 (ADDR_EXPR,
09596 build_pointer_type (type), node);
09597 if (TREE_SIDE_EFFECTS (node))
09598 TREE_SIDE_EFFECTS (item) = 1;
09599 if (staticp (node))
09600 TREE_CONSTANT (item) = 1;
09601 return fold (item);
09602 }
09603
09604
09605
09606
09607 tree
09608 ffecom_2 (enum tree_code code, tree type, tree node1,
09609 tree node2)
09610 {
09611 tree item;
09612
09613 if ((node1 == error_mark_node)
09614 || (node2 == error_mark_node)
09615 || (type == error_mark_node))
09616 return error_mark_node;
09617
09618 switch (ffe_is_emulate_complex () ? code : NOP_EXPR)
09619 {
09620 tree a, b, c, d, realtype;
09621
09622 case CONJ_EXPR:
09623 assert ("no CONJ_EXPR support yet" == NULL);
09624 return error_mark_node;
09625
09626 case COMPLEX_EXPR:
09627 item = build_tree_list (TYPE_FIELDS (type), node1);
09628 TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
09629 item = build (CONSTRUCTOR, type, NULL_TREE, item);
09630 break;
09631
09632 case PLUS_EXPR:
09633 if (TREE_CODE (type) != RECORD_TYPE)
09634 {
09635 item = build (code, type, node1, node2);
09636 break;
09637 }
09638 node1 = ffecom_stabilize_aggregate_ (node1);
09639 node2 = ffecom_stabilize_aggregate_ (node2);
09640 realtype = TREE_TYPE (TYPE_FIELDS (type));
09641 item =
09642 ffecom_2 (COMPLEX_EXPR, type,
09643 ffecom_2 (PLUS_EXPR, realtype,
09644 ffecom_1 (REALPART_EXPR, realtype,
09645 node1),
09646 ffecom_1 (REALPART_EXPR, realtype,
09647 node2)),
09648 ffecom_2 (PLUS_EXPR, realtype,
09649 ffecom_1 (IMAGPART_EXPR, realtype,
09650 node1),
09651 ffecom_1 (IMAGPART_EXPR, realtype,
09652 node2)));
09653 break;
09654
09655 case MINUS_EXPR:
09656 if (TREE_CODE (type) != RECORD_TYPE)
09657 {
09658 item = build (code, type, node1, node2);
09659 break;
09660 }
09661 node1 = ffecom_stabilize_aggregate_ (node1);
09662 node2 = ffecom_stabilize_aggregate_ (node2);
09663 realtype = TREE_TYPE (TYPE_FIELDS (type));
09664 item =
09665 ffecom_2 (COMPLEX_EXPR, type,
09666 ffecom_2 (MINUS_EXPR, realtype,
09667 ffecom_1 (REALPART_EXPR, realtype,
09668 node1),
09669 ffecom_1 (REALPART_EXPR, realtype,
09670 node2)),
09671 ffecom_2 (MINUS_EXPR, realtype,
09672 ffecom_1 (IMAGPART_EXPR, realtype,
09673 node1),
09674 ffecom_1 (IMAGPART_EXPR, realtype,
09675 node2)));
09676 break;
09677
09678 case MULT_EXPR:
09679 if (TREE_CODE (type) != RECORD_TYPE)
09680 {
09681 item = build (code, type, node1, node2);
09682 break;
09683 }
09684 node1 = ffecom_stabilize_aggregate_ (node1);
09685 node2 = ffecom_stabilize_aggregate_ (node2);
09686 realtype = TREE_TYPE (TYPE_FIELDS (type));
09687 a = save_expr (ffecom_1 (REALPART_EXPR, realtype,
09688 node1));
09689 b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
09690 node1));
09691 c = save_expr (ffecom_1 (REALPART_EXPR, realtype,
09692 node2));
09693 d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype,
09694 node2));
09695 item =
09696 ffecom_2 (COMPLEX_EXPR, type,
09697 ffecom_2 (MINUS_EXPR, realtype,
09698 ffecom_2 (MULT_EXPR, realtype,
09699 a,
09700 c),
09701 ffecom_2 (MULT_EXPR, realtype,
09702 b,
09703 d)),
09704 ffecom_2 (PLUS_EXPR, realtype,
09705 ffecom_2 (MULT_EXPR, realtype,
09706 a,
09707 d),
09708 ffecom_2 (MULT_EXPR, realtype,
09709 c,
09710 b)));
09711 break;
09712
09713 case EQ_EXPR:
09714 if ((TREE_CODE (node1) != RECORD_TYPE)
09715 && (TREE_CODE (node2) != RECORD_TYPE))
09716 {
09717 item = build (code, type, node1, node2);
09718 break;
09719 }
09720 assert (TREE_CODE (node1) == RECORD_TYPE);
09721 assert (TREE_CODE (node2) == RECORD_TYPE);
09722 node1 = ffecom_stabilize_aggregate_ (node1);
09723 node2 = ffecom_stabilize_aggregate_ (node2);
09724 realtype = TREE_TYPE (TYPE_FIELDS (type));
09725 item =
09726 ffecom_2 (TRUTH_ANDIF_EXPR, type,
09727 ffecom_2 (code, type,
09728 ffecom_1 (REALPART_EXPR, realtype,
09729 node1),
09730 ffecom_1 (REALPART_EXPR, realtype,
09731 node2)),
09732 ffecom_2 (code, type,
09733 ffecom_1 (IMAGPART_EXPR, realtype,
09734 node1),
09735 ffecom_1 (IMAGPART_EXPR, realtype,
09736 node2)));
09737 break;
09738
09739 case NE_EXPR:
09740 if ((TREE_CODE (node1) != RECORD_TYPE)
09741 && (TREE_CODE (node2) != RECORD_TYPE))
09742 {
09743 item = build (code, type, node1, node2);
09744 break;
09745 }
09746 assert (TREE_CODE (node1) == RECORD_TYPE);
09747 assert (TREE_CODE (node2) == RECORD_TYPE);
09748 node1 = ffecom_stabilize_aggregate_ (node1);
09749 node2 = ffecom_stabilize_aggregate_ (node2);
09750 realtype = TREE_TYPE (TYPE_FIELDS (type));
09751 item =
09752 ffecom_2 (TRUTH_ORIF_EXPR, type,
09753 ffecom_2 (code, type,
09754 ffecom_1 (REALPART_EXPR, realtype,
09755 node1),
09756 ffecom_1 (REALPART_EXPR, realtype,
09757 node2)),
09758 ffecom_2 (code, type,
09759 ffecom_1 (IMAGPART_EXPR, realtype,
09760 node1),
09761 ffecom_1 (IMAGPART_EXPR, realtype,
09762 node2)));
09763 break;
09764
09765 default:
09766 item = build (code, type, node1, node2);
09767 break;
09768 }
09769
09770 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2))
09771 TREE_SIDE_EFFECTS (item) = 1;
09772 return fold (item);
09773 }
09774
09775
09776
09777
09778
09779
09780
09781
09782
09783
09784
09785
09786
09787
09788
09789
09790
09791
09792
09793 bool
09794 ffecom_2pass_advise_entrypoint (ffesymbol entry)
09795 {
09796 ffebld list;
09797 ffebld mlist;
09798 ffebld plist;
09799 ffebld arg;
09800 ffebld item;
09801 ffesymbol s;
09802 ffeinfoBasictype bt = ffesymbol_basictype (entry);
09803 ffeinfoKindtype kt = ffesymbol_kindtype (entry);
09804 ffetargetCharacterSize size = ffesymbol_size (entry);
09805 bool ok;
09806
09807 if (ffecom_num_entrypoints_ == 0)
09808 {
09809
09810 assert (ffecom_primary_entry_ != NULL);
09811
09812 ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_);
09813 ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_);
09814 ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_);
09815
09816 for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_);
09817 list != NULL;
09818 list = ffebld_trail (list))
09819 {
09820 arg = ffebld_head (list);
09821 if (ffebld_op (arg) != FFEBLD_opSYMTER)
09822 continue;
09823 item = ffebld_new_item (arg, NULL);
09824 if (plist == NULL)
09825 ffecom_master_arglist_ = item;
09826 else
09827 ffebld_set_trail (plist, item);
09828 plist = item;
09829 }
09830 }
09831
09832
09833
09834
09835
09836
09837 if (!ffecom_is_altreturning_)
09838 {
09839 for (list = ffesymbol_dummyargs (entry);
09840 list != NULL;
09841 list = ffebld_trail (list))
09842 {
09843 arg = ffebld_head (list);
09844 if (ffebld_op (arg) == FFEBLD_opSTAR)
09845 {
09846 ffecom_is_altreturning_ = TRUE;
09847 break;
09848 }
09849 }
09850 }
09851
09852
09853
09854 switch (ffecom_master_bt_)
09855 {
09856 case FFEINFO_basictypeNONE:
09857 ok = (bt != FFEINFO_basictypeCHARACTER);
09858 break;
09859
09860 case FFEINFO_basictypeCHARACTER:
09861 ok
09862 = (bt == FFEINFO_basictypeCHARACTER)
09863 && (kt == ffecom_master_kt_)
09864 && (size == ffecom_master_size_);
09865 break;
09866
09867 case FFEINFO_basictypeANY:
09868 return FALSE;
09869
09870 default:
09871 if (bt == FFEINFO_basictypeCHARACTER)
09872 {
09873 ok = FALSE;
09874 break;
09875 }
09876 ok = TRUE;
09877 if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_))
09878 {
09879 ffecom_master_bt_ = FFEINFO_basictypeNONE;
09880 ffecom_master_kt_ = FFEINFO_kindtypeNONE;
09881 }
09882 break;
09883 }
09884
09885 if (!ok)
09886 {
09887 ffebad_start (FFEBAD_ENTRY_CONFLICTS);
09888 ffest_ffebad_here_current_stmt (0);
09889 ffebad_finish ();
09890 return FALSE;
09891 }
09892
09893
09894
09895 ++ffecom_num_entrypoints_;
09896
09897
09898
09899 for (list = ffesymbol_dummyargs (entry);
09900 list != NULL;
09901 list = ffebld_trail (list))
09902 {
09903 arg = ffebld_head (list);
09904 if (ffebld_op (arg) != FFEBLD_opSYMTER)
09905 continue;
09906 s = ffebld_symter (arg);
09907 for (plist = NULL, mlist = ffecom_master_arglist_;
09908 mlist != NULL;
09909 plist = mlist, mlist = ffebld_trail (mlist))
09910 {
09911
09912 if (ffebld_symter (ffebld_head (mlist)) == s)
09913 break;
09914 }
09915 if (mlist != NULL)
09916 continue;
09917
09918
09919
09920 item = ffebld_new_item (arg, NULL);
09921 if (plist == NULL)
09922 ffecom_master_arglist_ = item;
09923 else
09924 ffebld_set_trail (plist, item);
09925 }
09926
09927 return TRUE;
09928 }
09929
09930
09931
09932
09933
09934
09935
09936
09937
09938
09939 void
09940 ffecom_2pass_do_entrypoint (ffesymbol entry)
09941 {
09942 static int mfn_num = 0;
09943 static int ent_num;
09944
09945 if (mfn_num != ffecom_num_fns_)
09946 {
09947 ent_num = 1;
09948 mfn_num = ffecom_num_fns_;
09949 ffecom_do_entry_ (ffecom_primary_entry_, 0);
09950 }
09951 else
09952 ++ent_num;
09953
09954 --ffecom_num_entrypoints_;
09955
09956 ffecom_do_entry_ (entry, ent_num);
09957 }
09958
09959
09960
09961
09962
09963 tree
09964 ffecom_2s (enum tree_code code, tree type, tree node1,
09965 tree node2)
09966 {
09967 tree item;
09968
09969 if ((node1 == error_mark_node)
09970 || (node2 == error_mark_node)
09971 || (type == error_mark_node))
09972 return error_mark_node;
09973
09974 item = build (code, type, node1, node2);
09975 TREE_SIDE_EFFECTS (item) = 1;
09976 return fold (item);
09977 }
09978
09979
09980
09981
09982 tree
09983 ffecom_3 (enum tree_code code, tree type, tree node1,
09984 tree node2, tree node3)
09985 {
09986 tree item;
09987
09988 if ((node1 == error_mark_node)
09989 || (node2 == error_mark_node)
09990 || (node3 == error_mark_node)
09991 || (type == error_mark_node))
09992 return error_mark_node;
09993
09994 item = build (code, type, node1, node2, node3);
09995 if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)
09996 || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3)))
09997 TREE_SIDE_EFFECTS (item) = 1;
09998 return fold (item);
09999 }
10000
10001
10002
10003
10004
10005 tree
10006 ffecom_3s (enum tree_code code, tree type, tree node1,
10007 tree node2, tree node3)
10008 {
10009 tree item;
10010
10011 if ((node1 == error_mark_node)
10012 || (node2 == error_mark_node)
10013 || (node3 == error_mark_node)
10014 || (type == error_mark_node))
10015 return error_mark_node;
10016
10017 item = build (code, type, node1, node2, node3);
10018 TREE_SIDE_EFFECTS (item) = 1;
10019 return fold (item);
10020 }
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032
10033
10034
10035
10036
10037
10038
10039 tree
10040 ffecom_arg_expr (ffebld expr, tree *length)
10041 {
10042 tree ign;
10043
10044 *length = NULL_TREE;
10045
10046 if (expr == NULL)
10047 return integer_zero_node;
10048
10049 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10050 return ffecom_expr (expr);
10051
10052 return ffecom_arg_ptr_to_expr (expr, &ign);
10053 }
10054
10055
10056
10057
10058
10059
10060
10061
10062
10063
10064
10065 tree
10066 ffecom_arg_ptr_to_const_expr (ffebld expr, tree *length)
10067 {
10068 if (! expr)
10069 return integer_zero_node;
10070
10071 if (ffebld_op (expr) == FFEBLD_opANY)
10072 {
10073 if (length)
10074 *length = error_mark_node;
10075 return error_mark_node;
10076 }
10077
10078 if (ffebld_arity (expr) == 0
10079 && (ffebld_op (expr) != FFEBLD_opSYMTER
10080 || ffebld_where (expr) == FFEINFO_whereCOMMON
10081 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10082 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10083 {
10084 tree t;
10085
10086 t = ffecom_arg_ptr_to_expr (expr, length);
10087 assert (TREE_CONSTANT (t));
10088 assert (! length || TREE_CONSTANT (*length));
10089 return t;
10090 }
10091
10092 if (length
10093 && ffebld_size (expr) != FFETARGET_charactersizeNONE)
10094 *length = build_int_2 (ffebld_size (expr), 0);
10095 else if (length)
10096 *length = NULL_TREE;
10097 return NULL_TREE;
10098 }
10099
10100
10101
10102
10103
10104
10105
10106
10107
10108
10109
10110
10111
10112
10113
10114
10115
10116
10117
10118
10119
10120
10121
10122
10123 tree
10124 ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
10125 {
10126 tree item;
10127 tree ign_length;
10128 ffecomConcatList_ catlist;
10129
10130 if (length != NULL)
10131 *length = NULL_TREE;
10132
10133 if (expr == NULL)
10134 return integer_zero_node;
10135
10136 switch (ffebld_op (expr))
10137 {
10138 case FFEBLD_opPERCENT_VAL:
10139 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10140 return ffecom_expr (ffebld_left (expr));
10141 {
10142 tree temp_exp;
10143 tree temp_length;
10144
10145 temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);
10146 if (temp_exp == error_mark_node)
10147 return error_mark_node;
10148
10149 return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),
10150 temp_exp);
10151 }
10152
10153 case FFEBLD_opPERCENT_REF:
10154 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10155 return ffecom_ptr_to_expr (ffebld_left (expr));
10156 if (length != NULL)
10157 {
10158 ign_length = NULL_TREE;
10159 length = &ign_length;
10160 }
10161 expr = ffebld_left (expr);
10162 break;
10163
10164 case FFEBLD_opPERCENT_DESCR:
10165 switch (ffeinfo_basictype (ffebld_info (expr)))
10166 {
10167 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10168 case FFEINFO_basictypeHOLLERITH:
10169 #endif
10170 case FFEINFO_basictypeCHARACTER:
10171 break;
10172
10173 default:
10174 item = ffecom_ptr_to_expr (expr);
10175 if (item != error_mark_node)
10176 *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));
10177 break;
10178 }
10179 break;
10180
10181 default:
10182 break;
10183 }
10184
10185 #ifdef PASS_HOLLERITH_BY_DESCRIPTOR
10186 if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
10187 && (length != NULL))
10188 {
10189 ffetargetHollerith h;
10190
10191 assert (ffebld_op (expr) == FFEBLD_opCONTER);
10192 h = ffebld_cu_val_hollerith (ffebld_constant_union
10193 (ffebld_conter (expr)));
10194 *length
10195 = build_int_2 (h.length, 0);
10196 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10197 }
10198 #endif
10199
10200 if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
10201 return ffecom_ptr_to_expr (expr);
10202
10203 assert (ffeinfo_kindtype (ffebld_info (expr))
10204 == FFEINFO_kindtypeCHARACTER1);
10205
10206 while (ffebld_op (expr) == FFEBLD_opPAREN)
10207 expr = ffebld_left (expr);
10208
10209 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
10210 switch (ffecom_concat_list_count_ (catlist))
10211 {
10212 case 0:
10213 if (length != NULL)
10214 {
10215 *length = ffecom_f2c_ftnlen_zero_node;
10216 TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
10217 }
10218 ffecom_concat_list_kill_ (catlist);
10219 return null_pointer_node;
10220
10221 case 1:
10222 if (length == NULL)
10223 ffecom_char_args_with_null_ (&item, &ign_length,
10224 ffecom_concat_list_expr_ (catlist, 0));
10225 else
10226 ffecom_char_args_ (&item, length,
10227 ffecom_concat_list_expr_ (catlist, 0));
10228 ffecom_concat_list_kill_ (catlist);
10229 assert (item != NULL_TREE);
10230 return item;
10231
10232 default:
10233 break;
10234 }
10235
10236 {
10237 int count = ffecom_concat_list_count_ (catlist);
10238 int i;
10239 tree lengths;
10240 tree items;
10241 tree length_array;
10242 tree item_array;
10243 tree citem;
10244 tree clength;
10245 tree temporary;
10246 tree num;
10247 tree known_length;
10248 ffetargetCharacterSize sz;
10249
10250 sz = ffecom_concat_list_maxlen_ (catlist);
10251
10252 assert (sz != FFETARGET_charactersizeNONE);
10253
10254 #ifdef HOHO
10255 length_array
10256 = lengths
10257 = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,
10258 FFETARGET_charactersizeNONE, count, TRUE);
10259 item_array
10260 = items
10261 = ffecom_push_tempvar (ffecom_f2c_address_type_node,
10262 FFETARGET_charactersizeNONE, count, TRUE);
10263 temporary = ffecom_push_tempvar (char_type_node,
10264 sz, -1, TRUE);
10265 #else
10266 {
10267 tree hook;
10268
10269 hook = ffebld_nonter_hook (expr);
10270 assert (hook);
10271 assert (TREE_CODE (hook) == TREE_VEC);
10272 assert (TREE_VEC_LENGTH (hook) == 3);
10273 length_array = lengths = TREE_VEC_ELT (hook, 0);
10274 item_array = items = TREE_VEC_ELT (hook, 1);
10275 temporary = TREE_VEC_ELT (hook, 2);
10276 }
10277 #endif
10278
10279 known_length = ffecom_f2c_ftnlen_zero_node;
10280
10281 for (i = 0; i < count; ++i)
10282 {
10283 if ((i == count)
10284 && (length == NULL))
10285 ffecom_char_args_with_null_ (&citem, &clength,
10286 ffecom_concat_list_expr_ (catlist, i));
10287 else
10288 ffecom_char_args_ (&citem, &clength,
10289 ffecom_concat_list_expr_ (catlist, i));
10290 if ((citem == error_mark_node)
10291 || (clength == error_mark_node))
10292 {
10293 ffecom_concat_list_kill_ (catlist);
10294 *length = error_mark_node;
10295 return error_mark_node;
10296 }
10297
10298 items
10299 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),
10300 ffecom_modify (void_type_node,
10301 ffecom_2 (ARRAY_REF,
10302 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),
10303 item_array,
10304 build_int_2 (i, 0)),
10305 citem),
10306 items);
10307 clength = ffecom_save_tree (clength);
10308 if (length != NULL)
10309 known_length
10310 = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,
10311 known_length,
10312 clength);
10313 lengths
10314 = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),
10315 ffecom_modify (void_type_node,
10316 ffecom_2 (ARRAY_REF,
10317 TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),
10318 length_array,
10319 build_int_2 (i, 0)),
10320 clength),
10321 lengths);
10322 }
10323
10324 temporary = ffecom_1 (ADDR_EXPR,
10325 build_pointer_type (TREE_TYPE (temporary)),
10326 temporary);
10327
10328 item = build_tree_list (NULL_TREE, temporary);
10329 TREE_CHAIN (item)
10330 = build_tree_list (NULL_TREE,
10331 ffecom_1 (ADDR_EXPR,
10332 build_pointer_type (TREE_TYPE (items)),
10333 items));
10334 TREE_CHAIN (TREE_CHAIN (item))
10335 = build_tree_list (NULL_TREE,
10336 ffecom_1 (ADDR_EXPR,
10337 build_pointer_type (TREE_TYPE (lengths)),
10338 lengths));
10339 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))
10340 = build_tree_list
10341 (NULL_TREE,
10342 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,
10343 convert (ffecom_f2c_ftnlen_type_node,
10344 build_int_2 (count, 0))));
10345 num = build_int_2 (sz, 0);
10346 TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;
10347 TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))
10348 = build_tree_list (NULL_TREE, num);
10349
10350 item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);
10351 TREE_SIDE_EFFECTS (item) = 1;
10352 item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),
10353 item,
10354 temporary);
10355
10356 if (length != NULL)
10357 *length = known_length;
10358 }
10359
10360 ffecom_concat_list_kill_ (catlist);
10361 assert (item != NULL_TREE);
10362 return item;
10363 }
10364
10365
10366
10367
10368
10369
10370
10371
10372 tree
10373 ffecom_call_gfrt (ffecomGfrt ix, tree args, tree hook)
10374 {
10375 return ffecom_call_ (ffecom_gfrt_tree_ (ix),
10376 ffecom_gfrt_kindtype (ix),
10377 ffe_is_f2c_library () && ffecom_gfrt_complex_[ix],
10378 NULL_TREE, args, NULL_TREE, NULL,
10379 NULL, NULL_TREE, TRUE, hook);
10380 }
10381
10382
10383
10384 tree
10385 ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
10386 ffeinfoKindtype kt, tree tree_type)
10387 {
10388 tree item;
10389
10390 switch (bt)
10391 {
10392 case FFEINFO_basictypeINTEGER:
10393 {
10394 int val;
10395
10396 switch (kt)
10397 {
10398 #if FFETARGET_okINTEGER1
10399 case FFEINFO_kindtypeINTEGER1:
10400 val = ffebld_cu_val_integer1 (*cu);
10401 break;
10402 #endif
10403
10404 #if FFETARGET_okINTEGER2
10405 case FFEINFO_kindtypeINTEGER2:
10406 val = ffebld_cu_val_integer2 (*cu);
10407 break;
10408 #endif
10409
10410 #if FFETARGET_okINTEGER3
10411 case FFEINFO_kindtypeINTEGER3:
10412 val = ffebld_cu_val_integer3 (*cu);
10413 break;
10414 #endif
10415
10416 #if FFETARGET_okINTEGER4
10417 case FFEINFO_kindtypeINTEGER4:
10418 val = ffebld_cu_val_integer4 (*cu);
10419 break;
10420 #endif
10421
10422 default:
10423 assert ("bad INTEGER constant kind type" == NULL);
10424
10425 case FFEINFO_kindtypeANY:
10426 return error_mark_node;
10427 }
10428 item = build_int_2 (val, (val < 0) ? -1 : 0);
10429 TREE_TYPE (item) = tree_type;
10430 }
10431 break;
10432
10433 case FFEINFO_basictypeLOGICAL:
10434 {
10435 int val;
10436
10437 switch (kt)
10438 {
10439 #if FFETARGET_okLOGICAL1
10440 case FFEINFO_kindtypeLOGICAL1:
10441 val = ffebld_cu_val_logical1 (*cu);
10442 break;
10443 #endif
10444
10445 #if FFETARGET_okLOGICAL2
10446 case FFEINFO_kindtypeLOGICAL2:
10447 val = ffebld_cu_val_logical2 (*cu);
10448 break;
10449 #endif
10450
10451 #if FFETARGET_okLOGICAL3
10452 case FFEINFO_kindtypeLOGICAL3:
10453 val = ffebld_cu_val_logical3 (*cu);
10454 break;
10455 #endif
10456
10457 #if FFETARGET_okLOGICAL4
10458 case FFEINFO_kindtypeLOGICAL4:
10459 val = ffebld_cu_val_logical4 (*cu);
10460 break;
10461 #endif
10462
10463 default:
10464 assert ("bad LOGICAL constant kind type" == NULL);
10465
10466 case FFEINFO_kindtypeANY:
10467 return error_mark_node;
10468 }
10469 item = build_int_2 (val, (val < 0) ? -1 : 0);
10470 TREE_TYPE (item) = tree_type;
10471 }
10472 break;
10473
10474 case FFEINFO_basictypeREAL:
10475 {
10476 REAL_VALUE_TYPE val;
10477
10478 switch (kt)
10479 {
10480 #if FFETARGET_okREAL1
10481 case FFEINFO_kindtypeREAL1:
10482 val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu));
10483 break;
10484 #endif
10485
10486 #if FFETARGET_okREAL2
10487 case FFEINFO_kindtypeREAL2:
10488 val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu));
10489 break;
10490 #endif
10491
10492 #if FFETARGET_okREAL3
10493 case FFEINFO_kindtypeREAL3:
10494 val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu));
10495 break;
10496 #endif
10497
10498 #if FFETARGET_okREAL4
10499 case FFEINFO_kindtypeREAL4:
10500 val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
10501 break;
10502 #endif
10503
10504 default:
10505 assert ("bad REAL constant kind type" == NULL);
10506
10507 case FFEINFO_kindtypeANY:
10508 return error_mark_node;
10509 }
10510 item = build_real (tree_type, val);
10511 }
10512 break;
10513
10514 case FFEINFO_basictypeCOMPLEX:
10515 {
10516 REAL_VALUE_TYPE real;
10517 REAL_VALUE_TYPE imag;
10518 tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt];
10519
10520 switch (kt)
10521 {
10522 #if FFETARGET_okCOMPLEX1
10523 case FFEINFO_kindtypeREAL1:
10524 real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real);
10525 imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary);
10526 break;
10527 #endif
10528
10529 #if FFETARGET_okCOMPLEX2
10530 case FFEINFO_kindtypeREAL2:
10531 real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real);
10532 imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary);
10533 break;
10534 #endif
10535
10536 #if FFETARGET_okCOMPLEX3
10537 case FFEINFO_kindtypeREAL3:
10538 real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real);
10539 imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary);
10540 break;
10541 #endif
10542
10543 #if FFETARGET_okCOMPLEX4
10544 case FFEINFO_kindtypeREAL4:
10545 real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
10546 imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
10547 break;
10548 #endif
10549
10550 default:
10551 assert ("bad REAL constant kind type" == NULL);
10552
10553 case FFEINFO_kindtypeANY:
10554 return error_mark_node;
10555 }
10556 item = ffecom_build_complex_constant_ (tree_type,
10557 build_real (el_type, real),
10558 build_real (el_type, imag));
10559 }
10560 break;
10561
10562 case FFEINFO_basictypeCHARACTER:
10563 {
10564 ffetargetCharacter1 val;
10565
10566 switch (kt)
10567 {
10568 #if FFETARGET_okCHARACTER1
10569 case FFEINFO_kindtypeLOGICAL1:
10570 val = ffebld_cu_val_character1 (*cu);
10571 break;
10572 #endif
10573
10574 default:
10575 assert ("bad CHARACTER constant kind type" == NULL);
10576
10577 case FFEINFO_kindtypeANY:
10578 return error_mark_node;
10579 }
10580 item = build_string (ffetarget_length_character1 (val),
10581 ffetarget_text_character1 (val));
10582 TREE_TYPE (item)
10583 = build_type_variant (build_array_type (char_type_node,
10584 build_range_type
10585 (integer_type_node,
10586 integer_one_node,
10587 build_int_2
10588 (ffetarget_length_character1
10589 (val), 0))),
10590 1, 0);
10591 }
10592 break;
10593
10594 case FFEINFO_basictypeHOLLERITH:
10595 {
10596 ffetargetHollerith h;
10597
10598 h = ffebld_cu_val_hollerith (*cu);
10599
10600
10601 if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE)
10602 item = build_string (h.length, h.text);
10603 else
10604 {
10605 char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE];
10606
10607 memcpy (str, h.text, h.length);
10608 memset (&str[h.length], ' ',
10609 FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE
10610 - h.length);
10611 item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE,
10612 str);
10613 }
10614 TREE_TYPE (item)
10615 = build_type_variant (build_array_type (char_type_node,
10616 build_range_type
10617 (integer_type_node,
10618 integer_one_node,
10619 build_int_2
10620 (h.length, 0))),
10621 1, 0);
10622 }
10623 break;
10624
10625 case FFEINFO_basictypeTYPELESS:
10626 {
10627 ffetargetInteger1 ival;
10628 ffetargetTypeless tless;
10629 ffebad error;
10630
10631 tless = ffebld_cu_val_typeless (*cu);
10632 error = ffetarget_convert_integer1_typeless (&ival, tless);
10633 assert (error == FFEBAD);
10634
10635 item = build_int_2 ((int) ival, 0);
10636 }
10637 break;
10638
10639 default:
10640 assert ("not yet on constant type" == NULL);
10641
10642 case FFEINFO_basictypeANY:
10643 return error_mark_node;
10644 }
10645
10646 TREE_CONSTANT (item) = 1;
10647
10648 return item;
10649 }
10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660 tree
10661 ffecom_const_expr (ffebld expr)
10662 {
10663 if (! expr)
10664 return integer_zero_node;
10665
10666 if (ffebld_op (expr) == FFEBLD_opANY)
10667 return error_mark_node;
10668
10669 if (ffebld_arity (expr) == 0
10670 && (ffebld_op (expr) != FFEBLD_opSYMTER
10671 #if NEWCOMMON
10672
10673 || ffebld_where (expr) == FFEINFO_whereCOMMON
10674 #endif
10675 || ffebld_where (expr) == FFEINFO_whereGLOBAL
10676 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
10677 {
10678 tree t;
10679
10680 t = ffecom_expr (expr);
10681 assert (TREE_CONSTANT (t));
10682 return t;
10683 }
10684
10685 return NULL_TREE;
10686 }
10687
10688
10689
10690 tree
10691 ffecom_decl_field (tree context, tree prevfield,
10692 const char *name, tree type)
10693 {
10694 tree field;
10695
10696 field = build_decl (FIELD_DECL, get_identifier (name), type);
10697 DECL_CONTEXT (field) = context;
10698 DECL_ALIGN (field) = 0;
10699 DECL_USER_ALIGN (field) = 0;
10700 if (prevfield != NULL_TREE)
10701 TREE_CHAIN (prevfield) = field;
10702
10703 return field;
10704 }
10705
10706 void
10707 ffecom_close_include (FILE *f)
10708 {
10709 ffecom_close_include_ (f);
10710 }
10711
10712 int
10713 ffecom_decode_include_option (char *spec)
10714 {
10715 return ffecom_decode_include_option_ (spec);
10716 }
10717
10718
10719
10720 tree
10721 ffecom_end_compstmt (void)
10722 {
10723 return bison_rule_compstmt_ ();
10724 }
10725
10726
10727
10728
10729
10730
10731
10732 void
10733 ffecom_end_transition ()
10734 {
10735 ffebld item;
10736
10737 if (ffe_is_ffedebug ())
10738 fprintf (dmpout, "; end_stmt_transition\n");
10739
10740 ffecom_list_blockdata_ = NULL;
10741 ffecom_list_common_ = NULL;
10742
10743 ffesymbol_drive (ffecom_sym_end_transition);
10744 if (ffe_is_ffedebug ())
10745 {
10746 ffestorag_report ();
10747 }
10748
10749 ffecom_start_progunit_ ();
10750
10751 for (item = ffecom_list_blockdata_;
10752 item != NULL;
10753 item = ffebld_trail (item))
10754 {
10755 ffebld callee;
10756 ffesymbol s;
10757 tree dt;
10758 tree t;
10759 tree var;
10760 static int number = 0;
10761
10762 callee = ffebld_head (item);
10763 s = ffebld_symter (callee);
10764 t = ffesymbol_hook (s).decl_tree;
10765 if (t == NULL_TREE)
10766 {
10767 s = ffecom_sym_transform_ (s);
10768 t = ffesymbol_hook (s).decl_tree;
10769 }
10770
10771 dt = build_pointer_type (TREE_TYPE (t));
10772
10773 var = build_decl (VAR_DECL,
10774 ffecom_get_invented_identifier ("__g77_forceload_%d",
10775 number++),
10776 dt);
10777 DECL_EXTERNAL (var) = 0;
10778 TREE_STATIC (var) = 1;
10779 TREE_PUBLIC (var) = 0;
10780 DECL_INITIAL (var) = error_mark_node;
10781 TREE_USED (var) = 1;
10782
10783 var = start_decl (var, FALSE);
10784
10785 t = ffecom_1 (ADDR_EXPR, dt, t);
10786
10787 finish_decl (var, t, FALSE);
10788 }
10789
10790
10791
10792
10793 for (item = ffecom_list_common_;
10794 item != NULL;
10795 item = ffebld_trail (item))
10796 ffecom_transform_common_ (ffebld_symter (ffebld_head (item)));
10797
10798 ffecom_list_common_ = NULL;
10799 }
10800
10801
10802
10803
10804
10805
10806
10807
10808 void
10809 ffecom_exec_transition ()
10810 {
10811 bool inhibited;
10812
10813 if (ffe_is_ffedebug ())
10814 fprintf (dmpout, "; exec_stmt_transition\n");
10815
10816 inhibited = ffebad_inhibit ();
10817 ffebad_set_inhibit (FALSE);
10818
10819 ffesymbol_drive (ffecom_sym_exec_transition);
10820 ffeequiv_exec_transition ();
10821 if (ffe_is_ffedebug ())
10822 {
10823 ffestorag_report ();
10824 }
10825
10826 if (inhibited)
10827 ffebad_set_inhibit (TRUE);
10828 }
10829
10830
10831
10832
10833
10834
10835 void
10836 ffecom_expand_let_stmt (ffebld dest, ffebld source)
10837 {
10838 tree dest_tree;
10839 tree dest_length;
10840 tree source_tree;
10841 tree expr_tree;
10842
10843 if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER)
10844 {
10845 bool dest_used;
10846 tree assign_temp;
10847
10848
10849
10850
10851 if (ffebld_op (dest) != FFEBLD_opSYMTER
10852 || ((dest_tree = ffesymbol_hook (ffebld_symter (dest)).decl_tree)
10853 && (TREE_CODE (dest_tree) != VAR_DECL
10854 || TREE_ADDRESSABLE (dest_tree))))
10855 {
10856 ffecom_prepare_expr_ (source, dest);
10857 dest_used = TRUE;
10858 }
10859 else
10860 {
10861 ffecom_prepare_expr_ (source, NULL);
10862 dest_used = FALSE;
10863 }
10864
10865 ffecom_prepare_expr_w (NULL_TREE, dest);
10866
10867
10868
10869
10870 if (ffebld_basictype (dest) == FFEINFO_basictypeCOMPLEX
10871 && ffecom_possible_partial_overlap_ (dest, source))
10872 {
10873 assign_temp = ffecom_make_tempvar ("complex_let",
10874 ffecom_tree_type
10875 [ffebld_basictype (dest)]
10876 [ffebld_kindtype (dest)],
10877 FFETARGET_charactersizeNONE,
10878 -1);
10879 }
10880 else
10881 assign_temp = NULL_TREE;
10882
10883 ffecom_prepare_end ();
10884
10885 dest_tree = ffecom_expr_w (NULL_TREE, dest);
10886 if (dest_tree == error_mark_node)
10887 return;
10888
10889 if ((TREE_CODE (dest_tree) != VAR_DECL)
10890 || TREE_ADDRESSABLE (dest_tree))
10891 source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used,
10892 FALSE, FALSE);
10893 else
10894 {
10895 assert (! dest_used);
10896 dest_used = FALSE;
10897 source_tree = ffecom_expr (source);
10898 }
10899 if (source_tree == error_mark_node)
10900 return;
10901
10902 if (dest_used)
10903 expr_tree = source_tree;
10904 else if (assign_temp)
10905 {
10906 #ifdef MOVE_EXPR
10907
10908
10909
10910
10911
10912 expr_tree = ffecom_2s (MOVE_EXPR, void_type_node,
10913 dest_tree,
10914 source_tree);
10915 #else
10916 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10917 assign_temp,
10918 source_tree);
10919 expand_expr_stmt (expr_tree);
10920 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10921 dest_tree,
10922 assign_temp);
10923 #endif
10924 }
10925 else
10926 expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
10927 dest_tree,
10928 source_tree);
10929
10930 expand_expr_stmt (expr_tree);
10931 return;
10932 }
10933
10934 ffecom_prepare_let_char_ (ffebld_size_known (dest), source);
10935 ffecom_prepare_expr_w (NULL_TREE, dest);
10936
10937 ffecom_prepare_end ();
10938
10939 ffecom_char_args_ (&dest_tree, &dest_length, dest);
10940 ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest),
10941 source);
10942 }
10943
10944
10945
10946
10947
10948
10949
10950
10951
10952
10953 tree
10954 ffecom_expr (ffebld expr)
10955 {
10956 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE);
10957 }
10958
10959
10960
10961 tree
10962 ffecom_expr_assign (ffebld expr)
10963 {
10964 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10965 }
10966
10967
10968
10969 tree
10970 ffecom_expr_assign_w (ffebld expr)
10971 {
10972 return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE);
10973 }
10974
10975
10976
10977
10978
10979
10980
10981 tree
10982 ffecom_expr_rw (tree type, ffebld expr)
10983 {
10984 assert (expr != NULL);
10985
10986 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
10987
10988 return stabilize_reference (ffecom_expr (expr));
10989 }
10990
10991
10992
10993
10994
10995
10996
10997 tree
10998 ffecom_expr_w (tree type, ffebld expr)
10999 {
11000 assert (expr != NULL);
11001
11002 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
11003
11004 return stabilize_reference (ffecom_expr (expr));
11005 }
11006
11007
11008
11009 void
11010 ffecom_finish_compile ()
11011 {
11012 assert (ffecom_outer_function_decl_ == NULL_TREE);
11013 assert (current_function_decl == NULL_TREE);
11014
11015 ffeglobal_drive (ffecom_finish_global_);
11016 }
11017
11018
11019
11020 void
11021 ffecom_finish_decl (tree decl, tree init, bool is_top_level)
11022 {
11023 assert (!is_top_level);
11024 finish_decl (decl, init, FALSE);
11025 }
11026
11027
11028
11029 void
11030 ffecom_finish_progunit ()
11031 {
11032 ffecom_end_compstmt ();
11033
11034 ffecom_previous_function_decl_ = current_function_decl;
11035 ffecom_which_entrypoint_decl_ = NULL_TREE;
11036
11037 finish_function (0);
11038 }
11039
11040
11041
11042 tree
11043 ffecom_get_invented_identifier (const char *pattern, ...)
11044 {
11045 tree decl;
11046 char *nam;
11047 va_list ap;
11048
11049 va_start (ap, pattern);
11050 if (vasprintf (&nam, pattern, ap) == 0)
11051 abort ();
11052 va_end (ap);
11053 decl = get_identifier (nam);
11054 free (nam);
11055 IDENTIFIER_INVENTED (decl) = 1;
11056 return decl;
11057 }
11058
11059 ffeinfoBasictype
11060 ffecom_gfrt_basictype (ffecomGfrt gfrt)
11061 {
11062 assert (gfrt < FFECOM_gfrt);
11063
11064 switch (ffecom_gfrt_type_[gfrt])
11065 {
11066 case FFECOM_rttypeVOID_:
11067 case FFECOM_rttypeVOIDSTAR_:
11068 return FFEINFO_basictypeNONE;
11069
11070 case FFECOM_rttypeFTNINT_:
11071 return FFEINFO_basictypeINTEGER;
11072
11073 case FFECOM_rttypeINTEGER_:
11074 return FFEINFO_basictypeINTEGER;
11075
11076 case FFECOM_rttypeLONGINT_:
11077 return FFEINFO_basictypeINTEGER;
11078
11079 case FFECOM_rttypeLOGICAL_:
11080 return FFEINFO_basictypeLOGICAL;
11081
11082 case FFECOM_rttypeREAL_F2C_:
11083 case FFECOM_rttypeREAL_GNU_:
11084 return FFEINFO_basictypeREAL;
11085
11086 case FFECOM_rttypeCOMPLEX_F2C_:
11087 case FFECOM_rttypeCOMPLEX_GNU_:
11088 return FFEINFO_basictypeCOMPLEX;
11089
11090 case FFECOM_rttypeDOUBLE_:
11091 case FFECOM_rttypeDOUBLEREAL_:
11092 return FFEINFO_basictypeREAL;
11093
11094 case FFECOM_rttypeDBLCMPLX_F2C_:
11095 case FFECOM_rttypeDBLCMPLX_GNU_:
11096 return FFEINFO_basictypeCOMPLEX;
11097
11098 case FFECOM_rttypeCHARACTER_:
11099 return FFEINFO_basictypeCHARACTER;
11100
11101 default:
11102 return FFEINFO_basictypeANY;
11103 }
11104 }
11105
11106 ffeinfoKindtype
11107 ffecom_gfrt_kindtype (ffecomGfrt gfrt)
11108 {
11109 assert (gfrt < FFECOM_gfrt);
11110
11111 switch (ffecom_gfrt_type_[gfrt])
11112 {
11113 case FFECOM_rttypeVOID_:
11114 case FFECOM_rttypeVOIDSTAR_:
11115 return FFEINFO_kindtypeNONE;
11116
11117 case FFECOM_rttypeFTNINT_:
11118 return FFEINFO_kindtypeINTEGER1;
11119
11120 case FFECOM_rttypeINTEGER_:
11121 return FFEINFO_kindtypeINTEGER1;
11122
11123 case FFECOM_rttypeLONGINT_:
11124 return FFEINFO_kindtypeINTEGER4;
11125
11126 case FFECOM_rttypeLOGICAL_:
11127 return FFEINFO_kindtypeLOGICAL1;
11128
11129 case FFECOM_rttypeREAL_F2C_:
11130 case FFECOM_rttypeREAL_GNU_:
11131 return FFEINFO_kindtypeREAL1;
11132
11133 case FFECOM_rttypeCOMPLEX_F2C_:
11134 case FFECOM_rttypeCOMPLEX_GNU_:
11135 return FFEINFO_kindtypeREAL1;
11136
11137 case FFECOM_rttypeDOUBLE_:
11138 case FFECOM_rttypeDOUBLEREAL_:
11139 return FFEINFO_kindtypeREAL2;
11140
11141 case FFECOM_rttypeDBLCMPLX_F2C_:
11142 case FFECOM_rttypeDBLCMPLX_GNU_:
11143 return FFEINFO_kindtypeREAL2;
11144
11145 case FFECOM_rttypeCHARACTER_:
11146 return FFEINFO_kindtypeCHARACTER1;
11147
11148 default:
11149 return FFEINFO_kindtypeANY;
11150 }
11151 }
11152
11153 void
11154 ffecom_init_0 ()
11155 {
11156 tree endlink;
11157 int i;
11158 int j;
11159 tree t;
11160 tree field;
11161 ffetype type;
11162 ffetype base_type;
11163 tree double_ftype_double;
11164 tree float_ftype_float;
11165 tree ldouble_ftype_ldouble;
11166 tree ffecom_tree_ptr_to_fun_type_void;
11167
11168
11169
11170
11171
11172 if (ffe_is_do_internal_checks ())
11173 {
11174 static const char names[][12]
11175 =
11176 {"bar", "bletch", "foo", "foobar"};
11177 const char *name;
11178 unsigned long ul;
11179 double fl;
11180
11181 name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]),
11182 (int (*)(const void *, const void *)) strcmp);
11183 if (name != &names[0][2])
11184 {
11185 assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h"
11186 == NULL);
11187 abort ();
11188 }
11189
11190 ul = strtoul ("123456789", NULL, 10);
11191 if (ul != 123456789L)
11192 {
11193 assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\
11194 in proj.h" == NULL);
11195 abort ();
11196 }
11197
11198 fl = atof ("56.789");
11199 if ((fl < 56.788) || (fl > 56.79))
11200 {
11201 assert ("atof not type double, fix your #include <stdio.h>"
11202 == NULL);
11203 abort ();
11204 }
11205 }
11206
11207 ffecom_outer_function_decl_ = NULL_TREE;
11208 current_function_decl = NULL_TREE;
11209 named_labels = NULL_TREE;
11210 current_binding_level = NULL_BINDING_LEVEL;
11211 free_binding_level = NULL_BINDING_LEVEL;
11212
11213 pushlevel (0);
11214 global_binding_level = current_binding_level;
11215 current_binding_level->prep_state = 2;
11216
11217 build_common_tree_nodes (1);
11218
11219
11220 pushdecl (build_decl (TYPE_DECL, get_identifier ("int"),
11221 integer_type_node));
11222
11223 char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
11224 pushdecl (build_decl (TYPE_DECL, get_identifier ("char"),
11225 char_type_node));
11226 pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"),
11227 long_integer_type_node));
11228 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
11229 unsigned_type_node));
11230 pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"),
11231 long_unsigned_type_node));
11232 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"),
11233 long_long_integer_type_node));
11234 pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"),
11235 long_long_unsigned_type_node));
11236 pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"),
11237 short_integer_type_node));
11238 pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"),
11239 short_unsigned_type_node));
11240
11241
11242
11243
11244 set_sizetype
11245 (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))));
11246 ffecom_typesize_pointer_
11247 = TREE_INT_CST_LOW (TYPE_SIZE (sizetype)) / BITS_PER_UNIT;
11248
11249 build_common_tree_nodes_2 (0);
11250
11251
11252 pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"),
11253 signed_char_type_node));
11254
11255 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"),
11256 unsigned_char_type_node));
11257
11258 pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
11259 float_type_node));
11260 pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
11261 double_type_node));
11262 pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"),
11263 long_double_type_node));
11264
11265
11266 complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node);
11267 complex_float_type_node = ffecom_make_complex_type_ (float_type_node);
11268 complex_double_type_node = ffecom_make_complex_type_ (double_type_node);
11269 complex_long_double_type_node
11270 = ffecom_make_complex_type_ (long_double_type_node);
11271
11272 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"),
11273 complex_integer_type_node));
11274 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"),
11275 complex_float_type_node));
11276 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"),
11277 complex_double_type_node));
11278 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"),
11279 complex_long_double_type_node));
11280
11281 pushdecl (build_decl (TYPE_DECL, get_identifier ("void"),
11282 void_type_node));
11283
11284
11285 TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
11286 TYPE_USER_ALIGN (void_type_node) = 0;
11287
11288 string_type_node = build_pointer_type (char_type_node);
11289
11290 ffecom_tree_fun_type_void
11291 = build_function_type (void_type_node, NULL_TREE);
11292
11293 ffecom_tree_ptr_to_fun_type_void
11294 = build_pointer_type (ffecom_tree_fun_type_void);
11295
11296 endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
11297
11298 float_ftype_float
11299 = build_function_type (float_type_node,
11300 tree_cons (NULL_TREE, float_type_node, endlink));
11301
11302 double_ftype_double
11303 = build_function_type (double_type_node,
11304 tree_cons (NULL_TREE, double_type_node, endlink));
11305
11306 ldouble_ftype_ldouble
11307 = build_function_type (long_double_type_node,
11308 tree_cons (NULL_TREE, long_double_type_node,
11309 endlink));
11310
11311 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11312 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11313 {
11314 ffecom_tree_type[i][j] = NULL_TREE;
11315 ffecom_tree_fun_type[i][j] = NULL_TREE;
11316 ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE;
11317 ffecom_f2c_typecode_[i][j] = -1;
11318 }
11319
11320
11321
11322
11323
11324
11325
11326 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]
11327 = t = make_signed_type (FLOAT_TYPE_SIZE);
11328 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"),
11329 t));
11330 type = ffetype_new ();
11331 base_type = type;
11332 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1,
11333 type);
11334 ffetype_set_ams (type,
11335 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11336 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11337 ffetype_set_star (base_type,
11338 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11339 type);
11340 ffetype_set_kind (base_type, 1, type);
11341 ffecom_typesize_integer1_ = ffetype_size (type);
11342 assert (ffetype_size (type) == sizeof (ffetargetInteger1));
11343
11344 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1]
11345 = t = make_unsigned_type (FLOAT_TYPE_SIZE);
11346 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"),
11347 t));
11348
11349 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2]
11350 = t = make_signed_type (CHAR_TYPE_SIZE);
11351 pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"),
11352 t));
11353 type = ffetype_new ();
11354 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2,
11355 type);
11356 ffetype_set_ams (type,
11357 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11358 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11359 ffetype_set_star (base_type,
11360 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11361 type);
11362 ffetype_set_kind (base_type, 3, type);
11363 assert (ffetype_size (type) == sizeof (ffetargetInteger2));
11364
11365 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2]
11366 = t = make_unsigned_type (CHAR_TYPE_SIZE);
11367 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
11368 t));
11369
11370 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3]
11371 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11372 pushdecl (build_decl (TYPE_DECL, get_identifier ("word"),
11373 t));
11374 type = ffetype_new ();
11375 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3,
11376 type);
11377 ffetype_set_ams (type,
11378 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11379 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11380 ffetype_set_star (base_type,
11381 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11382 type);
11383 ffetype_set_kind (base_type, 6, type);
11384 assert (ffetype_size (type) == sizeof (ffetargetInteger3));
11385
11386 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3]
11387 = t = make_unsigned_type (CHAR_TYPE_SIZE * 2);
11388 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"),
11389 t));
11390
11391 ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4]
11392 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11393 pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"),
11394 t));
11395 type = ffetype_new ();
11396 ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4,
11397 type);
11398 ffetype_set_ams (type,
11399 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11400 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11401 ffetype_set_star (base_type,
11402 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11403 type);
11404 ffetype_set_kind (base_type, 2, type);
11405 assert (ffetype_size (type) == sizeof (ffetargetInteger4));
11406
11407 ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4]
11408 = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2);
11409 pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"),
11410 t));
11411
11412 #if 0
11413 if (ffe_is_do_internal_checks ()
11414 && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE
11415 && LONG_TYPE_SIZE != CHAR_TYPE_SIZE
11416 && LONG_TYPE_SIZE != SHORT_TYPE_SIZE
11417 && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE)
11418 {
11419 fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n",
11420 LONG_TYPE_SIZE);
11421 }
11422 #endif
11423
11424 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1]
11425 = t = make_signed_type (FLOAT_TYPE_SIZE);
11426 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"),
11427 t));
11428 type = ffetype_new ();
11429 base_type = type;
11430 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1,
11431 type);
11432 ffetype_set_ams (type,
11433 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11434 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11435 ffetype_set_star (base_type,
11436 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11437 type);
11438 ffetype_set_kind (base_type, 1, type);
11439 assert (ffetype_size (type) == sizeof (ffetargetLogical1));
11440
11441 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2]
11442 = t = make_signed_type (CHAR_TYPE_SIZE);
11443 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"),
11444 t));
11445 type = ffetype_new ();
11446 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2,
11447 type);
11448 ffetype_set_ams (type,
11449 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11450 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11451 ffetype_set_star (base_type,
11452 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11453 type);
11454 ffetype_set_kind (base_type, 3, type);
11455 assert (ffetype_size (type) == sizeof (ffetargetLogical2));
11456
11457 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3]
11458 = t = make_signed_type (CHAR_TYPE_SIZE * 2);
11459 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"),
11460 t));
11461 type = ffetype_new ();
11462 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3,
11463 type);
11464 ffetype_set_ams (type,
11465 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11466 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11467 ffetype_set_star (base_type,
11468 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11469 type);
11470 ffetype_set_kind (base_type, 6, type);
11471 assert (ffetype_size (type) == sizeof (ffetargetLogical3));
11472
11473 ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4]
11474 = t = make_signed_type (FLOAT_TYPE_SIZE * 2);
11475 pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"),
11476 t));
11477 type = ffetype_new ();
11478 ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4,
11479 type);
11480 ffetype_set_ams (type,
11481 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11482 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11483 ffetype_set_star (base_type,
11484 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11485 type);
11486 ffetype_set_kind (base_type, 2, type);
11487 assert (ffetype_size (type) == sizeof (ffetargetLogical4));
11488
11489 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11490 = t = make_node (REAL_TYPE);
11491 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE;
11492 pushdecl (build_decl (TYPE_DECL, get_identifier ("real"),
11493 t));
11494 layout_type (t);
11495 type = ffetype_new ();
11496 base_type = type;
11497 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1,
11498 type);
11499 ffetype_set_ams (type,
11500 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11501 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11502 ffetype_set_star (base_type,
11503 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11504 type);
11505 ffetype_set_kind (base_type, 1, type);
11506 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]
11507 = FFETARGET_f2cTYREAL;
11508 assert (ffetype_size (type) == sizeof (ffetargetReal1));
11509
11510 ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE]
11511 = t = make_node (REAL_TYPE);
11512 TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2;
11513 pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"),
11514 t));
11515 layout_type (t);
11516 type = ffetype_new ();
11517 ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE,
11518 type);
11519 ffetype_set_ams (type,
11520 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11521 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11522 ffetype_set_star (base_type,
11523 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11524 type);
11525 ffetype_set_kind (base_type, 2, type);
11526 ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]
11527 = FFETARGET_f2cTYDREAL;
11528 assert (ffetype_size (type) == sizeof (ffetargetReal2));
11529
11530 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11531 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]);
11532 pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"),
11533 t));
11534 type = ffetype_new ();
11535 base_type = type;
11536 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1,
11537 type);
11538 ffetype_set_ams (type,
11539 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11540 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11541 ffetype_set_star (base_type,
11542 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11543 type);
11544 ffetype_set_kind (base_type, 1, type);
11545 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1]
11546 = FFETARGET_f2cTYCOMPLEX;
11547 assert (ffetype_size (type) == sizeof (ffetargetComplex1));
11548
11549 ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE]
11550 = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]);
11551 pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"),
11552 t));
11553 type = ffetype_new ();
11554 ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE,
11555 type);
11556 ffetype_set_ams (type,
11557 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11558 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11559 ffetype_set_star (base_type,
11560 TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE,
11561 type);
11562 ffetype_set_kind (base_type, 2,
11563 type);
11564 ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2]
11565 = FFETARGET_f2cTYDCOMPLEX;
11566 assert (ffetype_size (type) == sizeof (ffetargetComplex2));
11567
11568
11569
11570 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11571 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11572 {
11573 if ((t = ffecom_tree_type[i][j]) != NULL_TREE)
11574 {
11575 if (i == FFEINFO_basictypeINTEGER)
11576 {
11577
11578
11579 if (GET_MODE_SIZE (TYPE_MODE (t))
11580 >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
11581 {
11582 if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE)
11583 || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_]))
11584 > GET_MODE_SIZE (TYPE_MODE (t))))
11585 ffecom_pointer_kind_ = j;
11586 }
11587 }
11588 else if (i == FFEINFO_basictypeCOMPLEX)
11589 t = void_type_node;
11590
11591
11592 else if ((i == FFEINFO_basictypeREAL)
11593 && (j == FFEINFO_kindtypeREAL1))
11594 t = ffecom_tree_type
11595 [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2];
11596
11597 t = ffecom_tree_fun_type[i][j] = build_function_type (t,
11598 NULL_TREE);
11599 ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t);
11600 }
11601 }
11602
11603
11604
11605 if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE)
11606 fatal_error ("no INTEGER type can hold a pointer on this configuration");
11607 else if (0 && ffe_is_do_internal_checks ())
11608 fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_);
11609 ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER,
11610 FFEINFO_kindtypeINTEGERDEFAULT),
11611 7,
11612 ffeinfo_type (FFEINFO_basictypeINTEGER,
11613 ffecom_pointer_kind_));
11614
11615 if (ffe_is_ugly_assign ())
11616 ffecom_label_kind_ = ffecom_pointer_kind_;
11617 else
11618 ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT;
11619 if (0 && ffe_is_do_internal_checks ())
11620 fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_);
11621
11622 ffecom_integer_type_node
11623 = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1];
11624 ffecom_integer_zero_node = convert (ffecom_integer_type_node,
11625 integer_zero_node);
11626 ffecom_integer_one_node = convert (ffecom_integer_type_node,
11627 integer_one_node);
11628
11629
11630
11631
11632
11633
11634
11635
11636
11637
11638
11639
11640 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE,
11641 FFETARGET_f2cTYLONG);
11642 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE,
11643 FFETARGET_f2cTYSHORT);
11644 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE,
11645 FFETARGET_f2cTYINT1);
11646 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE,
11647 FFETARGET_f2cTYQUAD);
11648 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE,
11649 FFETARGET_f2cTYLOGICAL);
11650 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE,
11651 FFETARGET_f2cTYLOGICAL2);
11652 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE,
11653 FFETARGET_f2cTYLOGICAL1);
11654
11655 ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE,
11656 FFETARGET_f2cTYQUAD);
11657
11658
11659
11660
11661 ffecom_tree_type[FFEINFO_basictypeCHARACTER]
11662 [FFEINFO_kindtypeCHARACTER1] = t = char_type_node;
11663 type = ffetype_new ();
11664 base_type = type;
11665 ffeinfo_set_type (FFEINFO_basictypeCHARACTER,
11666 FFEINFO_kindtypeCHARACTER1,
11667 type);
11668 ffetype_set_ams (type,
11669 TYPE_ALIGN (t) / BITS_PER_UNIT, 0,
11670 TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT);
11671 ffetype_set_kind (base_type, 1, type);
11672 assert (ffetype_size (type)
11673 == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0]));
11674
11675 ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER]
11676 [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void;
11677 ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER]
11678 [FFEINFO_kindtypeCHARACTER1]
11679 = ffecom_tree_ptr_to_fun_type_void;
11680 ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1]
11681 = FFETARGET_f2cTYCHAR;
11682
11683 ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY]
11684 = 0;
11685
11686
11687
11688 ffecom_multi_type_node_ = make_node (UNION_TYPE);
11689
11690 field = NULL_TREE;
11691
11692 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
11693 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
11694 {
11695 char name[30];
11696
11697 if (ffecom_tree_type[i][j] == NULL_TREE)
11698 continue;
11699 sprintf (&name[0], "bt_%s_kt_%s",
11700 ffeinfo_basictype_string ((ffeinfoBasictype) i),
11701 ffeinfo_kindtype_string ((ffeinfoKindtype) j));
11702 ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL,
11703 get_identifier (name),
11704 ffecom_tree_type[i][j]);
11705 DECL_CONTEXT (ffecom_multi_fields_[i][j])
11706 = ffecom_multi_type_node_;
11707 DECL_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11708 DECL_USER_ALIGN (ffecom_multi_fields_[i][j]) = 0;
11709 TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
11710 field = ffecom_multi_fields_[i][j];
11711 }
11712
11713 TYPE_FIELDS (ffecom_multi_type_node_) = field;
11714 layout_type (ffecom_multi_type_node_);
11715
11716
11717
11718
11719 ffecom_tree_subr_type
11720 = build_function_type (integer_type_node, NULL_TREE);
11721 ffecom_tree_ptr_to_subr_type
11722 = build_pointer_type (ffecom_tree_subr_type);
11723 ffecom_tree_blockdata_type
11724 = build_function_type (void_type_node, NULL_TREE);
11725
11726 builtin_function ("__builtin_sqrtf", float_ftype_float,
11727 BUILT_IN_SQRTF, BUILT_IN_NORMAL, "sqrtf");
11728 builtin_function ("__builtin_sqrt", double_ftype_double,
11729 BUILT_IN_SQRT, BUILT_IN_NORMAL, "sqrt");
11730 builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
11731 BUILT_IN_SQRTL, BUILT_IN_NORMAL, "sqrtl");
11732 builtin_function ("__builtin_sinf", float_ftype_float,
11733 BUILT_IN_SINF, BUILT_IN_NORMAL, "sinf");
11734 builtin_function ("__builtin_sin", double_ftype_double,
11735 BUILT_IN_SIN, BUILT_IN_NORMAL, "sin");
11736 builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
11737 BUILT_IN_SINL, BUILT_IN_NORMAL, "sinl");
11738 builtin_function ("__builtin_cosf", float_ftype_float,
11739 BUILT_IN_COSF, BUILT_IN_NORMAL, "cosf");
11740 builtin_function ("__builtin_cos", double_ftype_double,
11741 BUILT_IN_COS, BUILT_IN_NORMAL, "cos");
11742 builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
11743 BUILT_IN_COSL, BUILT_IN_NORMAL, "cosl");
11744
11745 pedantic_lvalues = FALSE;
11746
11747 ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
11748 FFECOM_f2cINTEGER,
11749 "integer");
11750 ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node,
11751 FFECOM_f2cADDRESS,
11752 "address");
11753 ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node,
11754 FFECOM_f2cREAL,
11755 "real");
11756 ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node,
11757 FFECOM_f2cDOUBLEREAL,
11758 "doublereal");
11759 ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node,
11760 FFECOM_f2cCOMPLEX,
11761 "complex");
11762 ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node,
11763 FFECOM_f2cDOUBLECOMPLEX,
11764 "doublecomplex");
11765 ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node,
11766 FFECOM_f2cLONGINT,
11767 "longint");
11768 ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node,
11769 FFECOM_f2cLOGICAL,
11770 "logical");
11771 ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node,
11772 FFECOM_f2cFLAG,
11773 "flag");
11774 ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node,
11775 FFECOM_f2cFTNLEN,
11776 "ftnlen");
11777 ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node,
11778 FFECOM_f2cFTNINT,
11779 "ftnint");
11780
11781 ffecom_f2c_ftnlen_zero_node
11782 = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node);
11783
11784 ffecom_f2c_ftnlen_one_node
11785 = convert (ffecom_f2c_ftnlen_type_node, integer_one_node);
11786
11787 ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0);
11788 TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node;
11789
11790 ffecom_f2c_ptr_to_ftnlen_type_node
11791 = build_pointer_type (ffecom_f2c_ftnlen_type_node);
11792
11793 ffecom_f2c_ptr_to_ftnint_type_node
11794 = build_pointer_type (ffecom_f2c_ftnint_type_node);
11795
11796 ffecom_f2c_ptr_to_integer_type_node
11797 = build_pointer_type (ffecom_f2c_integer_type_node);
11798
11799 ffecom_f2c_ptr_to_real_type_node
11800 = build_pointer_type (ffecom_f2c_real_type_node);
11801
11802 ffecom_float_zero_ = build_real (float_type_node, dconst0);
11803 ffecom_double_zero_ = build_real (double_type_node, dconst0);
11804 {
11805 REAL_VALUE_TYPE point_5;
11806
11807 #ifdef REAL_ARITHMETIC
11808 REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
11809 #else
11810 point_5 = .5;
11811 #endif
11812 ffecom_float_half_ = build_real (float_type_node, point_5);
11813 ffecom_double_half_ = build_real (double_type_node, point_5);
11814 }
11815
11816
11817
11818 ffecom_tree_xargc_ = build_decl (VAR_DECL,
11819 get_identifier ("f__xargc"),
11820 integer_type_node);
11821 DECL_EXTERNAL (ffecom_tree_xargc_) = 1;
11822 TREE_STATIC (ffecom_tree_xargc_) = 1;
11823 TREE_PUBLIC (ffecom_tree_xargc_) = 1;
11824 ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE);
11825 finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE);
11826
11827 #if 0
11828 if ((FLOAT_TYPE_SIZE != 32)
11829 || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32))
11830 {
11831 warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,",
11832 (int) FLOAT_TYPE_SIZE);
11833 warning ("and pointers are %d bits wide, but g77 doesn't yet work",
11834 (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))));
11835 warning ("properly unless they all are 32 bits wide");
11836 warning ("Please keep this in mind before you report bugs.");
11837 }
11838 #endif
11839
11840 #if 0
11841 if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)
11842 < TYPE_PRECISION (string_type_node))
11843
11844 warning ("configuration: char * holds %d bits, but ftnlen only %d",
11845 TYPE_PRECISION (string_type_node),
11846 TYPE_PRECISION (ffecom_f2c_ftnlen_type_node));
11847 #endif
11848
11849 #if 0
11850 if (TYPE_PRECISION (ffecom_integer_type_node)
11851 < TYPE_PRECISION (string_type_node))
11852
11853 warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\
11854 ASSIGN statement might fail",
11855 TYPE_PRECISION (string_type_node),
11856 TYPE_PRECISION (ffecom_integer_type_node));
11857 #endif
11858 }
11859
11860
11861
11862
11863
11864 void
11865 ffecom_init_2 ()
11866 {
11867 assert (ffecom_outer_function_decl_ == NULL_TREE);
11868 assert (current_function_decl == NULL_TREE);
11869 assert (ffecom_which_entrypoint_decl_ == NULL_TREE);
11870
11871 ffecom_master_arglist_ = NULL;
11872 ++ffecom_num_fns_;
11873 ffecom_primary_entry_ = NULL;
11874 ffecom_is_altreturning_ = FALSE;
11875 ffecom_func_result_ = NULL_TREE;
11876 ffecom_multi_retval_ = NULL_TREE;
11877 }
11878
11879
11880
11881
11882
11883
11884
11885
11886
11887 tree
11888 ffecom_list_expr (ffebld expr)
11889 {
11890 tree list;
11891 tree *plist = &list;
11892 tree trail = NULL_TREE;
11893 tree *ptrail = &trail;
11894 tree length;
11895
11896 while (expr != NULL)
11897 {
11898 tree texpr = ffecom_arg_expr (ffebld_head (expr), &length);
11899
11900 if (texpr == error_mark_node)
11901 return error_mark_node;
11902
11903 *plist = build_tree_list (NULL_TREE, texpr);
11904 plist = &TREE_CHAIN (*plist);
11905 expr = ffebld_trail (expr);
11906 if (length != NULL_TREE)
11907 {
11908 *ptrail = build_tree_list (NULL_TREE, length);
11909 ptrail = &TREE_CHAIN (*ptrail);
11910 }
11911 }
11912
11913 *plist = trail;
11914
11915 return list;
11916 }
11917
11918
11919
11920
11921
11922
11923
11924
11925
11926
11927 tree
11928 ffecom_list_ptr_to_expr (ffebld expr)
11929 {
11930 tree list;
11931 tree *plist = &list;
11932 tree trail = NULL_TREE;
11933 tree *ptrail = &trail;
11934 tree length;
11935
11936 while (expr != NULL)
11937 {
11938 tree texpr = ffecom_arg_ptr_to_expr (ffebld_head (expr), &length);
11939
11940 if (texpr == error_mark_node)
11941 return error_mark_node;
11942
11943 *plist = build_tree_list (NULL_TREE, texpr);
11944 plist = &TREE_CHAIN (*plist);
11945 expr = ffebld_trail (expr);
11946 if (length != NULL_TREE)
11947 {
11948 *ptrail = build_tree_list (NULL_TREE, length);
11949 ptrail = &TREE_CHAIN (*ptrail);
11950 }
11951 }
11952
11953 *plist = trail;
11954
11955 return list;
11956 }
11957
11958
11959
11960 tree
11961 ffecom_lookup_label (ffelab label)
11962 {
11963 tree glabel;
11964
11965 if (ffelab_hook (label) == NULL_TREE)
11966 {
11967 char labelname[16];
11968
11969 switch (ffelab_type (label))
11970 {
11971 case FFELAB_typeLOOPEND:
11972 case FFELAB_typeNOTLOOP:
11973 case FFELAB_typeENDIF:
11974 sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label));
11975 glabel = build_decl (LABEL_DECL, get_identifier (labelname),
11976 void_type_node);
11977 DECL_CONTEXT (glabel) = current_function_decl;
11978 DECL_MODE (glabel) = VOIDmode;
11979 break;
11980
11981 case FFELAB_typeFORMAT:
11982 glabel = build_decl (VAR_DECL,
11983 ffecom_get_invented_identifier
11984 ("__g77_format_%d", (int) ffelab_value (label)),
11985 build_type_variant (build_array_type
11986 (char_type_node,
11987 NULL_TREE),
11988 1, 0));
11989 TREE_CONSTANT (glabel) = 1;
11990 TREE_STATIC (glabel) = 1;
11991 DECL_CONTEXT (glabel) = current_function_decl;
11992 DECL_INITIAL (glabel) = NULL;
11993 make_decl_rtl (glabel, NULL);
11994 expand_decl (glabel);
11995
11996 ffecom_save_tree_forever (glabel);
11997
11998 break;
11999
12000 case FFELAB_typeANY:
12001 glabel = error_mark_node;
12002 break;
12003
12004 default:
12005 assert ("bad label type" == NULL);
12006 glabel = NULL;
12007 break;
12008 }
12009 ffelab_set_hook (label, glabel);
12010 }
12011 else
12012 {
12013 glabel = ffelab_hook (label);
12014 }
12015
12016 return glabel;
12017 }
12018
12019
12020
12021
12022
12023
12024 tree
12025 ffecom_modify (tree newtype, tree lhs,
12026 tree rhs)
12027 {
12028 if (lhs == error_mark_node || rhs == error_mark_node)
12029 return error_mark_node;
12030
12031 if (newtype == NULL_TREE)
12032 newtype = TREE_TYPE (lhs);
12033
12034 if (TREE_SIDE_EFFECTS (lhs))
12035 lhs = stabilize_reference (lhs);
12036
12037 return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs);
12038 }
12039
12040
12041
12042 void
12043 ffecom_file (const char *name)
12044 {
12045 ffecom_file_ (name);
12046 }
12047
12048
12049
12050
12051
12052
12053
12054
12055
12056
12057
12058
12059
12060
12061
12062
12063
12064
12065
12066
12067
12068
12069
12070
12071
12072
12073
12074
12075
12076 void
12077 ffecom_notify_init_storage (ffestorag st)
12078 {
12079 ffebld init;
12080
12081 if (ffestorag_init (st) == NULL)
12082 {
12083 init = ffestorag_accretion (st);
12084 assert (init != NULL);
12085 ffestorag_set_accretion (st, NULL);
12086 ffestorag_set_accretes (st, 0);
12087 ffestorag_set_init (st, init);
12088 }
12089 }
12090
12091
12092
12093
12094
12095
12096
12097
12098
12099
12100
12101
12102
12103
12104
12105
12106
12107
12108
12109
12110
12111
12112
12113
12114
12115
12116
12117
12118
12119 void
12120 ffecom_notify_init_symbol (ffesymbol s)
12121 {
12122 ffebld init;
12123
12124 if (ffesymbol_storage (s) == NULL)
12125 return;
12126
12127
12128 if ((ffesymbol_init (s) == NULL)
12129 && ((init = ffesymbol_accretion (s)) != NULL))
12130 {
12131 ffesymbol_set_accretion (s, NULL);
12132 ffesymbol_set_accretes (s, 0);
12133 ffesymbol_set_init (s, init);
12134 }
12135 }
12136
12137
12138
12139
12140
12141
12142
12143
12144
12145
12146 void
12147 ffecom_notify_primary_entry (ffesymbol s)
12148 {
12149 ffecom_primary_entry_ = s;
12150 ffecom_primary_entry_kind_ = ffesymbol_kind (s);
12151
12152 if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
12153 || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE))
12154 ffecom_primary_entry_is_proc_ = TRUE;
12155 else
12156 ffecom_primary_entry_is_proc_ = FALSE;
12157
12158 if (!ffe_is_silent ())
12159 {
12160 if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM)
12161 fprintf (stderr, "%s:\n", ffesymbol_text (s));
12162 else
12163 fprintf (stderr, " %s:\n", ffesymbol_text (s));
12164 }
12165
12166 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)
12167 {
12168 ffebld list;
12169 ffebld arg;
12170
12171 for (list = ffesymbol_dummyargs (s);
12172 list != NULL;
12173 list = ffebld_trail (list))
12174 {
12175 arg = ffebld_head (list);
12176 if (ffebld_op (arg) == FFEBLD_opSTAR)
12177 {
12178 ffecom_is_altreturning_ = TRUE;
12179 break;
12180 }
12181 }
12182 }
12183 }
12184
12185 FILE *
12186 ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c)
12187 {
12188 return ffecom_open_include_ (name, l, c);
12189 }
12190
12191
12192
12193
12194
12195
12196
12197
12198
12199 tree
12200 ffecom_ptr_to_expr (ffebld expr)
12201 {
12202 tree item;
12203 ffeinfoBasictype bt;
12204 ffeinfoKindtype kt;
12205 ffesymbol s;
12206
12207 assert (expr != NULL);
12208
12209 switch (ffebld_op (expr))
12210 {
12211 case FFEBLD_opSYMTER:
12212 s = ffebld_symter (expr);
12213 if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC)
12214 {
12215 ffecomGfrt ix;
12216
12217 ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr));
12218 assert (ix != FFECOM_gfrt);
12219 if ((item = ffecom_gfrt_[ix]) == NULL_TREE)
12220 {
12221 ffecom_make_gfrt_ (ix);
12222 item = ffecom_gfrt_[ix];
12223 }
12224 }
12225 else
12226 {
12227 item = ffesymbol_hook (s).decl_tree;
12228 if (item == NULL_TREE)
12229 {
12230 s = ffecom_sym_transform_ (s);
12231 item = ffesymbol_hook (s).decl_tree;
12232 }
12233 }
12234 assert (item != NULL);
12235 if (item == error_mark_node)
12236 return item;
12237 if (!ffesymbol_hook (s).addr)
12238 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12239 item);
12240 return item;
12241
12242 case FFEBLD_opARRAYREF:
12243 return ffecom_arrayref_ (NULL_TREE, expr, 1);
12244
12245 case FFEBLD_opCONTER:
12246
12247 bt = ffeinfo_basictype (ffebld_info (expr));
12248 kt = ffeinfo_kindtype (ffebld_info (expr));
12249
12250 item = ffecom_constantunion (&ffebld_constant_union
12251 (ffebld_conter (expr)), bt, kt,
12252 ffecom_tree_type[bt][kt]);
12253 if (item == error_mark_node)
12254 return error_mark_node;
12255 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12256 item);
12257 return item;
12258
12259 case FFEBLD_opANY:
12260 return error_mark_node;
12261
12262 default:
12263 bt = ffeinfo_basictype (ffebld_info (expr));
12264 kt = ffeinfo_kindtype (ffebld_info (expr));
12265
12266 item = ffecom_expr (expr);
12267 if (item == error_mark_node)
12268 return error_mark_node;
12269
12270
12271
12272
12273
12274
12275 STRIP_NOPS (item);
12276 if ((TREE_CODE (item) == VAR_DECL)
12277 || (TREE_CODE (item) == PARM_DECL)
12278 || (TREE_CODE (item) == RESULT_DECL)
12279 || (TREE_CODE (item) == INDIRECT_REF)
12280 || (TREE_CODE (item) == ARRAY_REF)
12281 || (TREE_CODE (item) == COMPONENT_REF)
12282 #ifdef OFFSET_REF
12283 || (TREE_CODE (item) == OFFSET_REF)
12284 #endif
12285 || (TREE_CODE (item) == BUFFER_REF)
12286 || (TREE_CODE (item) == REALPART_EXPR)
12287 || (TREE_CODE (item) == IMAGPART_EXPR))
12288 {
12289 item = ffecom_save_tree (item);
12290 }
12291
12292 item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)),
12293 item);
12294 return item;
12295 }
12296
12297 assert ("fall-through error" == NULL);
12298 return error_mark_node;
12299 }
12300
12301
12302
12303
12304
12305
12306
12307
12308 tree
12309 ffecom_make_tempvar (const char *commentary, tree type,
12310 ffetargetCharacterSize size, int elements)
12311 {
12312 tree t;
12313 static int mynumber;
12314
12315 assert (current_binding_level->prep_state < 2);
12316
12317 if (type == error_mark_node)
12318 return error_mark_node;
12319
12320 if (size != FFETARGET_charactersizeNONE)
12321 type = build_array_type (type,
12322 build_range_type (ffecom_f2c_ftnlen_type_node,
12323 ffecom_f2c_ftnlen_one_node,
12324 build_int_2 (size, 0)));
12325 if (elements != -1)
12326 type = build_array_type (type,
12327 build_range_type (integer_type_node,
12328 integer_zero_node,
12329 build_int_2 (elements - 1,
12330 0)));
12331 t = build_decl (VAR_DECL,
12332 ffecom_get_invented_identifier ("__g77_%s_%d",
12333 commentary,
12334 mynumber++),
12335 type);
12336
12337 t = start_decl (t, FALSE);
12338 finish_decl (t, NULL_TREE, FALSE);
12339
12340 return t;
12341 }
12342
12343
12344
12345
12346
12347
12348 void
12349 ffecom_prepare_arg_ptr_to_expr (ffebld expr)
12350 {
12351
12352 ffecom_prepare_expr (expr);
12353 return;
12354 }
12355
12356
12357
12358 bool
12359 ffecom_prepare_end (void)
12360 {
12361 int prep_state = current_binding_level->prep_state;
12362
12363 assert (prep_state < 2);
12364 current_binding_level->prep_state = 2;
12365
12366 return (prep_state == 1) ? TRUE : FALSE;
12367 }
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377
12378
12379
12380
12381
12382 void
12383 ffecom_prepare_expr_ (ffebld expr, ffebld dest UNUSED)
12384 {
12385 ffeinfoBasictype bt;
12386 ffeinfoKindtype kt;
12387 ffetargetCharacterSize sz;
12388 tree tempvar = NULL_TREE;
12389
12390 assert (current_binding_level->prep_state < 2);
12391
12392 if (! expr)
12393 return;
12394
12395 bt = ffeinfo_basictype (ffebld_info (expr));
12396 kt = ffeinfo_kindtype (ffebld_info (expr));
12397 sz = ffeinfo_size (ffebld_info (expr));
12398
12399
12400
12401
12402 if (bt == FFEINFO_basictypeCHARACTER)
12403 {
12404 while (ffebld_op (expr) == FFEBLD_opPAREN)
12405 expr = ffebld_left (expr);
12406 }
12407
12408 switch (ffebld_op (expr))
12409 {
12410 default:
12411
12412 if (ffebld_arity (expr) == 0)
12413 break;
12414
12415 switch (bt)
12416 {
12417 case FFEINFO_basictypeCOMPLEX:
12418 if (ffebld_op (expr) == FFEBLD_opFUNCREF)
12419 {
12420 ffesymbol s;
12421
12422 if (ffebld_op (ffebld_left (expr)) != FFEBLD_opSYMTER)
12423 break;
12424
12425 s = ffebld_symter (ffebld_left (expr));
12426 if (ffesymbol_where (s) == FFEINFO_whereCONSTANT
12427 || (ffesymbol_where (s) != FFEINFO_whereINTRINSIC
12428 && ! ffesymbol_is_f2c (s))
12429 || (ffesymbol_where (s) == FFEINFO_whereINTRINSIC
12430 && ! ffe_is_f2c_library ()))
12431 break;
12432 }
12433 else if (ffebld_op (expr) == FFEBLD_opPOWER)
12434 {
12435
12436
12437
12438 kt = FFEINFO_kindtypeREAL2;
12439 }
12440 else if (ffebld_op (expr) != FFEBLD_opDIVIDE)
12441
12442 break;
12443
12444
12445
12446 tempvar = ffecom_make_tempvar ("complex",
12447 ffecom_tree_type
12448 [FFEINFO_basictypeCOMPLEX][kt],
12449 FFETARGET_charactersizeNONE,
12450 -1);
12451 break;
12452
12453 case FFEINFO_basictypeCHARACTER:
12454 if (ffebld_op (expr) != FFEBLD_opFUNCREF)
12455 break;
12456
12457 if (sz == FFETARGET_charactersizeNONE)
12458
12459 sz = 24;
12460
12461 tempvar = ffecom_make_tempvar ("char", char_type_node, sz, -1);
12462 break;
12463
12464 default:
12465 break;
12466 }
12467 break;
12468
12469 #ifdef HAHA
12470 case FFEBLD_opPOWER:
12471 {
12472 tree rtype, ltype;
12473 tree rtmp, ltmp, result;
12474
12475 ltype = ffecom_type_expr (ffebld_left (expr));
12476 rtype = ffecom_type_expr (ffebld_right (expr));
12477
12478 rtmp = ffecom_make_tempvar (rtype, FFETARGET_charactersizeNONE, -1);
12479 ltmp = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12480 result = ffecom_make_tempvar (ltype, FFETARGET_charactersizeNONE, -1);
12481
12482 tempvar = make_tree_vec (3);
12483 TREE_VEC_ELT (tempvar, 0) = rtmp;
12484 TREE_VEC_ELT (tempvar, 1) = ltmp;
12485 TREE_VEC_ELT (tempvar, 2) = result;
12486 }
12487 break;
12488 #endif
12489
12490 case FFEBLD_opCONCATENATE:
12491 {
12492
12493
12494
12495
12496 ffecomConcatList_ catlist;
12497 tree ltmp, itmp, result;
12498 int count;
12499 int i;
12500
12501 catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);
12502 count = ffecom_concat_list_count_ (catlist);
12503
12504 if (count >= 2)
12505 {
12506 ltmp
12507 = ffecom_make_tempvar ("concat_len",
12508 ffecom_f2c_ftnlen_type_node,
12509 FFETARGET_charactersizeNONE, count);
12510 itmp
12511 = ffecom_make_tempvar ("concat_item",
12512 ffecom_f2c_address_type_node,
12513 FFETARGET_charactersizeNONE, count);
12514 result
12515 = ffecom_make_tempvar ("concat_res",
12516 char_type_node,
12517 ffecom_concat_list_maxlen_ (catlist),
12518 -1);
12519
12520 tempvar = make_tree_vec (3);
12521 TREE_VEC_ELT (tempvar, 0) = ltmp;
12522 TREE_VEC_ELT (tempvar, 1) = itmp;
12523 TREE_VEC_ELT (tempvar, 2) = result;
12524 }
12525
12526 for (i = 0; i < count; ++i)
12527 ffecom_prepare_arg_ptr_to_expr (ffecom_concat_list_expr_ (catlist,
12528 i));
12529
12530 ffecom_concat_list_kill_ (catlist);
12531
12532 if (tempvar)
12533 {
12534 ffebld_nonter_set_hook (expr, tempvar);
12535 current_binding_level->prep_state = 1;
12536 }
12537 }
12538 return;
12539
12540 case FFEBLD_opCONVERT:
12541 if (bt == FFEINFO_basictypeCHARACTER
12542 && ((ffebld_size_known (ffebld_left (expr))
12543 == FFETARGET_charactersizeNONE)
12544 || (ffebld_size_known (ffebld_left (expr)) >= sz)))
12545 tempvar = ffecom_make_tempvar ("convert", char_type_node, sz, -1);
12546 break;
12547 }
12548
12549 if (tempvar)
12550 {
12551 ffebld_nonter_set_hook (expr, tempvar);
12552 current_binding_level->prep_state = 1;
12553 }
12554
12555
12556
12557 switch (ffebld_op (expr))
12558 {
12559 case FFEBLD_opPERCENT_LOC:
12560 ffecom_prepare_ptr_to_expr (ffebld_left (expr));
12561 break;
12562
12563 case FFEBLD_opPERCENT_VAL:
12564 case FFEBLD_opPERCENT_REF:
12565 ffecom_prepare_expr (ffebld_left (expr));
12566 break;
12567
12568 case FFEBLD_opPERCENT_DESCR:
12569 ffecom_prepare_arg_ptr_to_expr (ffebld_left (expr));
12570 break;
12571
12572 case FFEBLD_opITEM:
12573 {
12574 ffebld item;
12575
12576 for (item = expr;
12577 item != NULL;
12578 item = ffebld_trail (item))
12579 if (ffebld_head (item) != NULL)
12580 ffecom_prepare_expr (ffebld_head (item));
12581 }
12582 break;
12583
12584 default:
12585
12586 switch (ffebld_arity (expr))
12587 {
12588 case 2:
12589 ffecom_prepare_expr (ffebld_left (expr));
12590 ffecom_prepare_expr (ffebld_right (expr));
12591 break;
12592
12593 case 1:
12594 ffecom_prepare_expr (ffebld_left (expr));
12595 break;
12596
12597 default:
12598 break;
12599 }
12600 }
12601
12602 return;
12603 }
12604
12605
12606
12607
12608
12609
12610 void
12611 ffecom_prepare_expr_rw (tree type, ffebld expr)
12612 {
12613
12614 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
12615
12616
12617 ffecom_prepare_expr (expr);
12618 return;
12619 }
12620
12621
12622
12623
12624
12625
12626 void
12627 ffecom_prepare_expr_w (tree type, ffebld expr)
12628 {
12629
12630 assert (type == NULL_TREE || type == ffecom_type_expr (expr));
12631
12632
12633 ffecom_prepare_expr (expr);
12634 return;
12635 }
12636
12637
12638
12639
12640
12641
12642 void
12643 ffecom_prepare_return_expr (ffebld expr)
12644 {
12645 assert (current_binding_level->prep_state < 2);
12646
12647 if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE
12648 && ffecom_is_altreturning_
12649 && expr != NULL)
12650 ffecom_prepare_expr (expr);
12651 }
12652
12653
12654
12655
12656
12657
12658 void
12659 ffecom_prepare_ptr_to_expr (ffebld expr)
12660 {
12661
12662 ffecom_prepare_expr (expr);
12663 return;
12664 }
12665
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676 tree
12677 ffecom_ptr_to_const_expr (ffebld expr)
12678 {
12679 if (! expr)
12680 return integer_zero_node;
12681
12682 if (ffebld_op (expr) == FFEBLD_opANY)
12683 return error_mark_node;
12684
12685 if (ffebld_arity (expr) == 0
12686 && (ffebld_op (expr) != FFEBLD_opSYMTER
12687 || ffebld_where (expr) == FFEINFO_whereCOMMON
12688 || ffebld_where (expr) == FFEINFO_whereGLOBAL
12689 || ffebld_where (expr) == FFEINFO_whereINTRINSIC))
12690 {
12691 tree t;
12692
12693 t = ffecom_ptr_to_expr (expr);
12694 assert (TREE_CONSTANT (t));
12695 return t;
12696 }
12697
12698 return NULL_TREE;
12699 }
12700
12701
12702
12703
12704
12705
12706
12707
12708
12709
12710
12711
12712
12713
12714 tree
12715 ffecom_return_expr (ffebld expr)
12716 {
12717 tree rtn;
12718
12719 switch (ffecom_primary_entry_kind_)
12720 {
12721 case FFEINFO_kindPROGRAM:
12722 case FFEINFO_kindBLOCKDATA:
12723 rtn = NULL_TREE;
12724 break;
12725
12726 case FFEINFO_kindSUBROUTINE:
12727 if (!ffecom_is_altreturning_)
12728 rtn = NULL_TREE;
12729 else if (expr == NULL)
12730 rtn = integer_zero_node;
12731 else
12732 rtn = ffecom_expr (expr);
12733 break;
12734
12735 case FFEINFO_kindFUNCTION:
12736 if ((ffecom_multi_retval_ != NULL_TREE)
12737 || (ffesymbol_basictype (ffecom_primary_entry_)
12738 == FFEINFO_basictypeCHARACTER)
12739 || ((ffesymbol_basictype (ffecom_primary_entry_)
12740 == FFEINFO_basictypeCOMPLEX)
12741 && (ffecom_num_entrypoints_ == 0)
12742 && ffesymbol_is_f2c (ffecom_primary_entry_)))
12743 {
12744
12745 rtn = NULL_TREE;
12746 break;
12747 }
12748 rtn = ffecom_func_result_;
12749 #if 0
12750
12751
12752
12753
12754
12755
12756
12757
12758
12759
12760
12761 if ((rtn == NULL_TREE)
12762 || !TREE_USED (rtn))
12763 {
12764 ffebad_start (FFEBAD_RETURN_VALUE_UNSET);
12765 ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_),
12766 ffesymbol_where_column (ffecom_primary_entry_));
12767 ffebad_string (ffesymbol_text (ffesymbol_funcresult
12768 (ffecom_primary_entry_)));
12769 ffebad_finish ();
12770 }
12771 #endif
12772 break;
12773
12774 default:
12775 assert ("bad unit kind" == NULL);
12776 case FFEINFO_kindANY:
12777 rtn = error_mark_node;
12778 break;
12779 }
12780
12781 return rtn;
12782 }
12783
12784
12785
12786 tree
12787 ffecom_save_tree (tree t)
12788 {
12789 return save_expr (t);
12790 }
12791
12792
12793
12794 void
12795 ffecom_start_compstmt (void)
12796 {
12797 bison_rule_pushlevel_ ();
12798 }
12799
12800
12801
12802 tree
12803 ffecom_start_decl (tree decl, bool is_initialized)
12804 {
12805 DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE;
12806 return start_decl (decl, FALSE);
12807 }
12808
12809
12810
12811
12812
12813
12814
12815
12816
12817 void
12818 ffecom_sym_commit (ffesymbol s UNUSED)
12819 {
12820 assert (!ffesymbol_retractable ());
12821 }
12822
12823
12824
12825
12826
12827
12828
12829
12830
12831
12832
12833 ffesymbol
12834 ffecom_sym_end_transition (ffesymbol s)
12835 {
12836 ffestorag st;
12837
12838 assert (!ffesymbol_retractable ());
12839
12840 s = ffest_sym_end_transition (s);
12841
12842 if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA)
12843 && (ffesymbol_where (s) == FFEINFO_whereGLOBAL))
12844 {
12845 ffecom_list_blockdata_
12846 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12847 FFEINTRIN_specNONE,
12848 FFEINTRIN_impNONE),
12849 ffecom_list_blockdata_);
12850 }
12851
12852
12853
12854
12855 if (ffesymbol_accretion (s) != NULL)
12856 {
12857 assert (ffesymbol_init (s) == NULL);
12858 ffecom_notify_init_symbol (s);
12859 }
12860 else if (((st = ffesymbol_storage (s)) != NULL)
12861 && ((st = ffestorag_parent (st)) != NULL)
12862 && (ffestorag_accretion (st) != NULL))
12863 {
12864 assert (ffestorag_init (st) == NULL);
12865 ffecom_notify_init_storage (st);
12866 }
12867
12868 if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON)
12869 && (ffesymbol_where (s) == FFEINFO_whereLOCAL)
12870 && (ffesymbol_storage (s) != NULL))
12871 {
12872 ffecom_list_common_
12873 = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE,
12874 FFEINTRIN_specNONE,
12875 FFEINTRIN_impNONE),
12876 ffecom_list_common_);
12877 }
12878
12879 return s;
12880 }
12881
12882
12883
12884
12885
12886
12887
12888
12889
12890
12891
12892 ffesymbol
12893 ffecom_sym_exec_transition (ffesymbol s)
12894 {
12895 s = ffest_sym_exec_transition (s);
12896
12897 return s;
12898 }
12899
12900
12901
12902
12903
12904
12905
12906
12907
12908
12909
12910
12911
12912
12913
12914
12915
12916
12917
12918
12919
12920
12921
12922
12923
12924
12925
12926
12927
12928
12929
12930
12931
12932
12933
12934
12935
12936
12937
12938
12939 ffesymbol
12940 ffecom_sym_learned (ffesymbol s)
12941 {
12942 ffestorag_exec_layout (s);
12943
12944 return s;
12945 }
12946
12947
12948
12949
12950
12951
12952
12953
12954
12955 void
12956 ffecom_sym_retract (ffesymbol s UNUSED)
12957 {
12958 assert (!ffesymbol_retractable ());
12959
12960 #if 0
12961
12962 switch (ffesymbol_hook (s).state)
12963 {
12964 case 0:
12965 break;
12966
12967 case 1:
12968 break;
12969
12970 case 2:
12971 break;
12972
12973 case 3:
12974 break;
12975
12976 case 4:
12977 break;
12978
12979 default:
12980 assert ("bad hook state" == NULL);
12981 break;
12982 }
12983 #endif
12984 }
12985
12986
12987
12988 tree
12989 ffecom_temp_label ()
12990 {
12991 tree glabel;
12992 static int mynumber = 0;
12993
12994 glabel = build_decl (LABEL_DECL,
12995 ffecom_get_invented_identifier ("__g77_label_%d",
12996 mynumber++),
12997 void_type_node);
12998 DECL_CONTEXT (glabel) = current_function_decl;
12999 DECL_MODE (glabel) = VOIDmode;
13000
13001 return glabel;
13002 }
13003
13004
13005
13006
13007
13008
13009 tree
13010 ffecom_truth_value (tree expr)
13011 {
13012 return truthvalue_conversion (expr);
13013 }
13014
13015
13016
13017
13018
13019
13020
13021 tree
13022 ffecom_truth_value_invert (tree expr)
13023 {
13024 return invert_truthvalue (ffecom_truth_value (expr));
13025 }
13026
13027
13028
13029
13030
13031 tree
13032 ffecom_type_expr (ffebld expr)
13033 {
13034 ffeinfoBasictype bt;
13035 ffeinfoKindtype kt;
13036 tree tree_type;
13037
13038 assert (expr != NULL);
13039
13040 bt = ffeinfo_basictype (ffebld_info (expr));
13041 kt = ffeinfo_kindtype (ffebld_info (expr));
13042 tree_type = ffecom_tree_type[bt][kt];
13043
13044 switch (ffebld_op (expr))
13045 {
13046 case FFEBLD_opCONTER:
13047 case FFEBLD_opSYMTER:
13048 case FFEBLD_opARRAYREF:
13049 case FFEBLD_opUPLUS:
13050 case FFEBLD_opPAREN:
13051 case FFEBLD_opUMINUS:
13052 case FFEBLD_opADD:
13053 case FFEBLD_opSUBTRACT:
13054 case FFEBLD_opMULTIPLY:
13055 case FFEBLD_opDIVIDE:
13056 case FFEBLD_opPOWER:
13057 case FFEBLD_opNOT:
13058 case FFEBLD_opFUNCREF:
13059 case FFEBLD_opSUBRREF:
13060 case FFEBLD_opAND:
13061 case FFEBLD_opOR:
13062 case FFEBLD_opXOR:
13063 case FFEBLD_opNEQV:
13064 case FFEBLD_opEQV:
13065 case FFEBLD_opCONVERT:
13066 case FFEBLD_opLT:
13067 case FFEBLD_opLE:
13068 case FFEBLD_opEQ:
13069 case FFEBLD_opNE:
13070 case FFEBLD_opGT:
13071 case FFEBLD_opGE:
13072 case FFEBLD_opPERCENT_LOC:
13073 return tree_type;
13074
13075 case FFEBLD_opACCTER:
13076 case FFEBLD_opARRTER:
13077 case FFEBLD_opITEM:
13078 case FFEBLD_opSTAR:
13079 case FFEBLD_opBOUNDS:
13080 case FFEBLD_opREPEAT:
13081 case FFEBLD_opLABTER:
13082 case FFEBLD_opLABTOK:
13083 case FFEBLD_opIMPDO:
13084 case FFEBLD_opCONCATENATE:
13085 case FFEBLD_opSUBSTR:
13086 default:
13087 assert ("bad op for ffecom_type_expr" == NULL);
13088
13089 case FFEBLD_opANY:
13090 return error_mark_node;
13091 }
13092 }
13093
13094
13095
13096
13097
13098
13099
13100
13101
13102 tree
13103 ffecom_which_entrypoint_decl ()
13104 {
13105 assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
13106
13107 return ffecom_which_entrypoint_decl_;
13108 }
13109
13110
13111
13112
13113
13114
13115
13116
13117
13118
13119
13120
13121
13122
13123
13124
13125 static void
13126 bison_rule_pushlevel_ ()
13127 {
13128 emit_line_note (input_filename, lineno);
13129 pushlevel (0);
13130 clear_last_expr ();
13131 expand_start_bindings (0);
13132 }
13133
13134 static tree
13135 bison_rule_compstmt_ ()
13136 {
13137 tree t;
13138 int keep = kept_level_p ();
13139
13140
13141 if (! keep)
13142 current_binding_level->names = NULL_TREE;
13143
13144 emit_line_note (input_filename, lineno);
13145 expand_end_bindings (getdecls (), keep, 0);
13146 t = poplevel (keep, 1, 0);
13147
13148 return t;
13149 }
13150
13151
13152
13153
13154
13155
13156
13157
13158
13159 tree
13160 builtin_function (const char *name, tree type, int function_code,
13161 enum built_in_class class,
13162 const char *library_name)
13163 {
13164 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
13165 DECL_EXTERNAL (decl) = 1;
13166 TREE_PUBLIC (decl) = 1;
13167 if (library_name)
13168 SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
13169 make_decl_rtl (decl, NULL);
13170 pushdecl (decl);
13171 DECL_BUILT_IN_CLASS (decl) = class;
13172 DECL_FUNCTION_CODE (decl) = function_code;
13173
13174 return decl;
13175 }
13176
13177
13178
13179
13180
13181
13182
13183
13184
13185 static int
13186 duplicate_decls (tree newdecl, tree olddecl)
13187 {
13188 int types_match = 1;
13189 int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
13190 && DECL_INITIAL (newdecl) != 0);
13191 tree oldtype = TREE_TYPE (olddecl);
13192 tree newtype = TREE_TYPE (newdecl);
13193
13194 if (olddecl == newdecl)
13195 return 1;
13196
13197 if (TREE_CODE (newtype) == ERROR_MARK
13198 || TREE_CODE (oldtype) == ERROR_MARK)
13199 types_match = 0;
13200
13201
13202
13203
13204 if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
13205 return 0;
13206
13207
13208
13209 if (types_match && TREE_CODE (newdecl) == PARM_DECL
13210 && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
13211 return 1;
13212
13213
13214
13215
13216
13217
13218 if (TREE_CODE (olddecl) == FUNCTION_DECL
13219 && DECL_BUILT_IN (olddecl))
13220 {
13221
13222 if (!TREE_PUBLIC (newdecl))
13223 return 0;
13224 else if (!types_match)
13225 {
13226
13227 tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl));
13228 tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl));
13229
13230 if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
13231 {
13232
13233
13234 tree newtype
13235 = build_function_type (newreturntype,
13236 TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
13237
13238 types_match = 1;
13239 if (types_match)
13240 TREE_TYPE (olddecl) = newtype;
13241 }
13242 }
13243 if (!types_match)
13244 return 0;
13245 }
13246 else if (TREE_CODE (olddecl) == FUNCTION_DECL
13247 && DECL_SOURCE_LINE (olddecl) == 0)
13248 {
13249
13250
13251 if (!TREE_PUBLIC (newdecl))
13252 return 0;
13253 else if (!types_match)
13254 {
13255
13256
13257
13258 TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
13259 }
13260 }
13261
13262
13263
13264
13265
13266
13267
13268 if (types_match)
13269 {
13270
13271 if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
13272 TREE_TYPE (newdecl)
13273 = TREE_TYPE (olddecl)
13274 = TREE_TYPE (newdecl);
13275
13276
13277 if (oldtype != TREE_TYPE (newdecl))
13278 {
13279 if (TREE_TYPE (newdecl) != error_mark_node)
13280 layout_type (TREE_TYPE (newdecl));
13281 if (TREE_CODE (newdecl) != FUNCTION_DECL
13282 && TREE_CODE (newdecl) != TYPE_DECL
13283 && TREE_CODE (newdecl) != CONST_DECL)
13284 layout_decl (newdecl, 0);
13285 }
13286 else
13287 {
13288
13289 DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
13290 DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
13291 if (TREE_CODE (olddecl) != FUNCTION_DECL)
13292 if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
13293 {
13294 DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
13295 DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
13296 }
13297 }
13298
13299
13300 COPY_DECL_RTL (olddecl, newdecl);
13301
13302
13303 if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
13304 && !TREE_THIS_VOLATILE (newdecl))
13305 TREE_THIS_VOLATILE (olddecl) = 0;
13306 if (TREE_READONLY (newdecl))
13307 TREE_READONLY (olddecl) = 1;
13308 if (TREE_THIS_VOLATILE (newdecl))
13309 {
13310 TREE_THIS_VOLATILE (olddecl) = 1;
13311 if (TREE_CODE (newdecl) == VAR_DECL)
13312 make_var_volatile (newdecl);
13313 }
13314
13315
13316
13317 if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
13318 || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
13319 {
13320 DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
13321 DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
13322
13323 if (DECL_CONTEXT (olddecl) == 0
13324 && TREE_CODE (newdecl) != FUNCTION_DECL)
13325 DECL_CONTEXT (newdecl) = 0;
13326 }
13327
13328
13329 if (DECL_IN_SYSTEM_HEADER (olddecl))
13330 DECL_IN_SYSTEM_HEADER (newdecl) = 1;
13331 else if (DECL_IN_SYSTEM_HEADER (newdecl))
13332 DECL_IN_SYSTEM_HEADER (olddecl) = 1;
13333
13334
13335 if (DECL_INITIAL (newdecl) == 0)
13336 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13337
13338
13339
13340
13341
13342 if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
13343 DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
13344
13345 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13346 {
13347 DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
13348 DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
13349 }
13350 }
13351
13352
13353 else
13354 {
13355 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13356 TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
13357 TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
13358 TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
13359 }
13360
13361
13362
13363 if (TREE_CODE (newdecl) == FUNCTION_DECL)
13364 {
13365 TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
13366
13367
13368 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13369
13370 if (! TREE_PUBLIC (olddecl))
13371 TREE_PUBLIC (DECL_NAME (olddecl)) = 0;
13372 }
13373 if (DECL_EXTERNAL (newdecl))
13374 {
13375 TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
13376 DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
13377
13378 TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
13379 }
13380 else
13381 {
13382 TREE_STATIC (olddecl) = TREE_STATIC (newdecl);
13383 TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
13384 }
13385
13386
13387
13388 if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
13389 DECL_INLINE (olddecl) = 1;
13390 DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
13391
13392
13393
13394 if (TREE_CODE (newdecl) == FUNCTION_DECL
13395 && DECL_BUILT_IN (olddecl)
13396 && (!types_match || new_is_definition))
13397 {
13398 TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
13399 DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
13400 }
13401
13402
13403
13404
13405 if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition)
13406 {
13407 if (DECL_BUILT_IN (olddecl))
13408 {
13409 DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
13410 DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
13411 }
13412
13413 DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
13414 DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
13415 DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
13416 DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
13417 }
13418
13419
13420
13421 {
13422 register unsigned olddecl_uid = DECL_UID (olddecl);
13423
13424 memcpy ((char *) olddecl + sizeof (struct tree_common),
13425 (char *) newdecl + sizeof (struct tree_common),
13426 sizeof (struct tree_decl) - sizeof (struct tree_common));
13427 DECL_UID (olddecl) = olddecl_uid;
13428 }
13429
13430 return 1;
13431 }
13432
13433
13434
13435
13436
13437
13438 static void
13439 finish_decl (tree decl, tree init, bool is_top_level)
13440 {
13441 register tree type = TREE_TYPE (decl);
13442 int was_incomplete = (DECL_SIZE (decl) == 0);
13443 bool at_top_level = (current_binding_level == global_binding_level);
13444 bool top_level = is_top_level || at_top_level;
13445
13446
13447
13448 assert (!is_top_level || !at_top_level);
13449
13450 if (TREE_CODE (decl) == PARM_DECL)
13451 assert (init == NULL_TREE);
13452
13453
13454 else if (init == NULL_TREE)
13455 assert (DECL_INITIAL (decl) == NULL_TREE);
13456 else
13457 assert (DECL_INITIAL (decl) == error_mark_node);
13458
13459 if (init != NULL_TREE)
13460 {
13461 if (TREE_CODE (decl) != TYPE_DECL)
13462 DECL_INITIAL (decl) = init;
13463 else
13464 {
13465
13466 TREE_TYPE (decl) = TREE_TYPE (init);
13467 DECL_INITIAL (decl) = init = 0;
13468 }
13469 }
13470
13471
13472
13473 if (TREE_CODE (type) == ARRAY_TYPE
13474 && TYPE_DOMAIN (type) == 0
13475 && TREE_CODE (decl) != TYPE_DECL)
13476 {
13477 assert (top_level);
13478 assert (was_incomplete);
13479
13480 layout_decl (decl, 0);
13481 }
13482
13483 if (TREE_CODE (decl) == VAR_DECL)
13484 {
13485 if (DECL_SIZE (decl) == NULL_TREE
13486 && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
13487 layout_decl (decl, 0);
13488
13489 if (DECL_SIZE (decl) == NULL_TREE
13490 && (TREE_STATIC (decl)
13491 ?
13492
13493
13494
13495
13496 (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0)
13497 :
13498
13499 !DECL_EXTERNAL (decl)))
13500 {
13501 assert ("storage size not known" == NULL);
13502 abort ();
13503 }
13504
13505 if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
13506 && (DECL_SIZE (decl) != 0)
13507 && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST))
13508 {
13509 assert ("storage size not constant" == NULL);
13510 abort ();
13511 }
13512 }
13513
13514
13515
13516
13517
13518 if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
13519 {
13520 rest_of_decl_compilation (decl, NULL,
13521 DECL_CONTEXT (decl) == 0,
13522 0);
13523
13524 if (DECL_CONTEXT (decl) != 0)
13525 {
13526
13527
13528 if (was_incomplete
13529 && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
13530 {
13531
13532 TREE_ADDRESSABLE (decl) = TREE_USED (decl);
13533
13534 if (DECL_SIZE (decl) == 0)
13535 DECL_INITIAL (decl) = 0;
13536 expand_decl (decl);
13537 }
13538
13539 if (TREE_CODE (decl) != FUNCTION_DECL)
13540 expand_decl_init (decl);
13541 }
13542 }
13543 else if (TREE_CODE (decl) == TYPE_DECL)
13544 {
13545 rest_of_decl_compilation (decl, NULL,
13546 DECL_CONTEXT (decl) == 0,
13547 0);
13548 }
13549
13550
13551
13552
13553 if (current_binding_level == global_binding_level)
13554 get_pending_sizes ();
13555 }
13556
13557
13558
13559
13560
13561
13562
13563
13564
13565 static void
13566 finish_function (int nested)
13567 {
13568 register tree fndecl = current_function_decl;
13569
13570 assert (fndecl != NULL_TREE);
13571 if (TREE_CODE (fndecl) != ERROR_MARK)
13572 {
13573 if (nested)
13574 assert (DECL_CONTEXT (fndecl) != NULL_TREE);
13575 else
13576 assert (DECL_CONTEXT (fndecl) == NULL_TREE);
13577 }
13578
13579
13580
13581
13582
13583 poplevel (1, 0, 1);
13584
13585 if (TREE_CODE (fndecl) != ERROR_MARK)
13586 {
13587 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
13588
13589
13590
13591 DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
13592
13593
13594
13595 expand_function_end (input_filename, lineno, 0);
13596
13597
13598
13599 if (nested)
13600 ggc_push_context ();
13601
13602
13603 rest_of_compilation (fndecl);
13604
13605
13606 if (nested)
13607 ggc_pop_context ();
13608 }
13609
13610 if (TREE_CODE (fndecl) != ERROR_MARK
13611 && !nested
13612 && DECL_SAVED_INSNS (fndecl) == 0)
13613 {
13614
13615
13616
13617
13618
13619 if (DECL_INITIAL (fndecl) != 0)
13620 DECL_INITIAL (fndecl) = error_mark_node;
13621 DECL_ARGUMENTS (fndecl) = 0;
13622 }
13623
13624 if (!nested)
13625 {
13626
13627
13628
13629 ffecom_outer_function_decl_ = current_function_decl = NULL;
13630 }
13631 }
13632
13633
13634
13635
13636
13637
13638
13639
13640
13641 static const char *
13642 lang_printable_name (tree decl, int v)
13643 {
13644
13645
13646
13647 switch (v)
13648 {
13649 default:
13650 if (TREE_CODE (decl) == ERROR_MARK)
13651 return "erroneous code";
13652 return IDENTIFIER_POINTER (DECL_NAME (decl));
13653 }
13654 }
13655
13656
13657
13658
13659 static void
13660 lang_print_error_function (diagnostic_context *context __attribute__((unused)),
13661 const char *file)
13662 {
13663 static ffeglobal last_g = NULL;
13664 static ffesymbol last_s = NULL;
13665 ffeglobal g;
13666 ffesymbol s;
13667 const char *kind;
13668
13669 if ((ffecom_primary_entry_ == NULL)
13670 || (ffesymbol_global (ffecom_primary_entry_) == NULL))
13671 {
13672 g = NULL;
13673 s = NULL;
13674 kind = NULL;
13675 }
13676 else
13677 {
13678 g = ffesymbol_global (ffecom_primary_entry_);
13679 if (ffecom_nested_entry_ == NULL)
13680 {
13681 s = ffecom_primary_entry_;
13682 kind = _(ffeinfo_kind_message (ffesymbol_kind (s)));
13683 }
13684 else
13685 {
13686 s = ffecom_nested_entry_;
13687 kind = _("In statement function");
13688 }
13689 }
13690
13691 if ((last_g != g) || (last_s != s))
13692 {
13693 if (file)
13694 fprintf (stderr, "%s: ", file);
13695
13696 if (s == NULL)
13697 fprintf (stderr, _("Outside of any program unit:\n"));
13698 else
13699 {
13700 const char *name = ffesymbol_text (s);
13701
13702 fprintf (stderr, "%s `%s':\n", kind, name);
13703 }
13704
13705 last_g = g;
13706 last_s = s;
13707 }
13708 }
13709
13710
13711
13712 static tree
13713 lookup_name_current_level (tree name)
13714 {
13715 register tree t;
13716
13717 if (current_binding_level == global_binding_level)
13718 return IDENTIFIER_GLOBAL_VALUE (name);
13719
13720 if (IDENTIFIER_LOCAL_VALUE (name) == 0)
13721 return 0;
13722
13723 for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
13724 if (DECL_NAME (t) == name)
13725 break;
13726
13727 return t;
13728 }
13729
13730
13731
13732 static struct binding_level *
13733 make_binding_level ()
13734 {
13735
13736 return (struct binding_level *) xmalloc (sizeof (struct binding_level));
13737 }
13738
13739
13740
13741
13742
13743 struct f_function
13744 {
13745 struct f_function *next;
13746 tree named_labels;
13747 tree shadowed_labels;
13748 struct binding_level *binding_level;
13749 };
13750
13751 struct f_function *f_function_chain;
13752
13753
13754
13755 static void
13756 pop_f_function_context ()
13757 {
13758 struct f_function *p = f_function_chain;
13759 tree link;
13760
13761
13762 for (link = shadowed_labels; link; link = TREE_CHAIN (link))
13763 if (DECL_NAME (TREE_VALUE (link)) != 0)
13764 IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
13765 = TREE_VALUE (link);
13766
13767 if (current_function_decl != error_mark_node
13768 && DECL_SAVED_INSNS (current_function_decl) == 0)
13769 {
13770
13771
13772
13773 DECL_INITIAL (current_function_decl) = error_mark_node;
13774 DECL_ARGUMENTS (current_function_decl) = 0;
13775 }
13776
13777 pop_function_context ();
13778
13779 f_function_chain = p->next;
13780
13781 named_labels = p->named_labels;
13782 shadowed_labels = p->shadowed_labels;
13783 current_binding_level = p->binding_level;
13784
13785 free (p);
13786 }
13787
13788
13789
13790
13791 static void
13792 push_f_function_context ()
13793 {
13794 struct f_function *p
13795 = (struct f_function *) xmalloc (sizeof (struct f_function));
13796
13797 push_function_context ();
13798
13799 p->next = f_function_chain;
13800 f_function_chain = p;
13801
13802 p->named_labels = named_labels;
13803 p->shadowed_labels = shadowed_labels;
13804 p->binding_level = current_binding_level;
13805 }
13806
13807 static void
13808 push_parm_decl (tree parm)
13809 {
13810 int old_immediate_size_expand = immediate_size_expand;
13811
13812
13813
13814 immediate_size_expand = 0;
13815
13816
13817
13818 DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
13819 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
13820 TREE_READONLY (parm) = 1;
13821
13822 parm = pushdecl (parm);
13823
13824 immediate_size_expand = old_immediate_size_expand;
13825
13826 finish_decl (parm, NULL_TREE, FALSE);
13827 }
13828
13829
13830
13831 static tree
13832 pushdecl_top_level (x)
13833 tree x;
13834 {
13835 register tree t;
13836 register struct binding_level *b = current_binding_level;
13837 register tree f = current_function_decl;
13838
13839 current_binding_level = global_binding_level;
13840 current_function_decl = NULL_TREE;
13841 t = pushdecl (x);
13842 current_binding_level = b;
13843 current_function_decl = f;
13844 return t;
13845 }
13846
13847
13848
13849
13850
13851 static tree
13852 storedecls (decls)
13853 tree decls;
13854 {
13855 return current_binding_level->names = decls;
13856 }
13857
13858
13859
13860
13861
13862
13863
13864
13865 static void
13866 store_parm_decls (int is_main_program UNUSED)
13867 {
13868 register tree fndecl = current_function_decl;
13869
13870 if (fndecl == error_mark_node)
13871 return;
13872
13873
13874 DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
13875
13876
13877
13878 init_function_start (fndecl, input_filename, lineno);
13879
13880
13881
13882 expand_function_start (fndecl, 0);
13883 }
13884
13885 static tree
13886 start_decl (tree decl, bool is_top_level)
13887 {
13888 register tree tem;
13889 bool at_top_level = (current_binding_level == global_binding_level);
13890 bool top_level = is_top_level || at_top_level;
13891
13892
13893
13894 assert (!is_top_level || !at_top_level);
13895
13896 if (DECL_INITIAL (decl) != NULL_TREE)
13897 {
13898 assert (DECL_INITIAL (decl) == error_mark_node);
13899 assert (!DECL_EXTERNAL (decl));
13900 }
13901 else if (top_level)
13902 assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1);
13903
13904
13905 DECL_COMMON (decl) = 1;
13906
13907
13908
13909 if (is_top_level)
13910 tem = pushdecl_top_level (decl);
13911 else
13912 tem = pushdecl (decl);
13913
13914
13915 if (!top_level
13916
13917
13918 && !DECL_RTL_SET_P (tem))
13919 {
13920 if (TYPE_SIZE (TREE_TYPE (tem)) != 0)
13921 expand_decl (tem);
13922 else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
13923 && DECL_INITIAL (tem) != 0)
13924 expand_decl (tem);
13925 }
13926
13927 return tem;
13928 }
13929
13930
13931
13932
13933
13934
13935
13936
13937
13938
13939
13940
13941
13942
13943
13944 static void
13945 start_function (tree name, tree type, int nested, int public)
13946 {
13947 tree decl1;
13948 tree restype;
13949 int old_immediate_size_expand = immediate_size_expand;
13950
13951 named_labels = 0;
13952 shadowed_labels = 0;
13953
13954
13955 immediate_size_expand = 0;
13956
13957 if (nested)
13958 {
13959 assert (!public);
13960 assert (current_function_decl != NULL_TREE);
13961 assert (DECL_CONTEXT (current_function_decl) == NULL_TREE);
13962 }
13963 else
13964 {
13965 assert (current_function_decl == NULL_TREE);
13966 }
13967
13968 if (TREE_CODE (type) == ERROR_MARK)
13969 decl1 = current_function_decl = error_mark_node;
13970 else
13971 {
13972 decl1 = build_decl (FUNCTION_DECL,
13973 name,
13974 type);
13975 TREE_PUBLIC (decl1) = public ? 1 : 0;
13976 if (nested)
13977 DECL_INLINE (decl1) = 1;
13978 TREE_STATIC (decl1) = 1;
13979 DECL_EXTERNAL (decl1) = 0;
13980
13981 announce_function (decl1);
13982
13983
13984
13985 DECL_INITIAL (decl1) = error_mark_node;
13986
13987
13988
13989
13990 current_function_decl = pushdecl (decl1);
13991 }
13992
13993 if (!nested)
13994 ffecom_outer_function_decl_ = current_function_decl;
13995
13996 pushlevel (0);
13997 current_binding_level->prep_state = 2;
13998
13999 if (TREE_CODE (current_function_decl) != ERROR_MARK)
14000 {
14001 make_decl_rtl (current_function_decl, NULL);
14002
14003 restype = TREE_TYPE (TREE_TYPE (current_function_decl));
14004 DECL_RESULT (current_function_decl)
14005 = build_decl (RESULT_DECL, NULL_TREE, restype);
14006 }
14007
14008 if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK))
14009 TREE_ADDRESSABLE (current_function_decl) = 1;
14010
14011 immediate_size_expand = old_immediate_size_expand;
14012 }
14013
14014
14015
14016 tree
14017 convert (type, expr)
14018 tree type, expr;
14019 {
14020 register tree e = expr;
14021 register enum tree_code code = TREE_CODE (type);
14022
14023 if (type == TREE_TYPE (e)
14024 || TREE_CODE (e) == ERROR_MARK)
14025 return e;
14026 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
14027 return fold (build1 (NOP_EXPR, type, e));
14028 if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK
14029 || code == ERROR_MARK)
14030 return error_mark_node;
14031 if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE)
14032 {
14033 assert ("void value not ignored as it ought to be" == NULL);
14034 return error_mark_node;
14035 }
14036 if (code == VOID_TYPE)
14037 return build1 (CONVERT_EXPR, type, e);
14038 if ((code != RECORD_TYPE)
14039 && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE))
14040 e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))),
14041 e);
14042 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
14043 return fold (convert_to_integer (type, e));
14044 if (code == POINTER_TYPE)
14045 return fold (convert_to_pointer (type, e));
14046 if (code == REAL_TYPE)
14047 return fold (convert_to_real (type, e));
14048 if (code == COMPLEX_TYPE)
14049 return fold (convert_to_complex (type, e));
14050 if (code == RECORD_TYPE)
14051 return fold (ffecom_convert_to_complex_ (type, e));
14052
14053 assert ("conversion to non-scalar type requested" == NULL);
14054 return error_mark_node;
14055 }
14056
14057
14058
14059
14060 void
14061 copy_lang_decl (node)
14062 tree node UNUSED;
14063 {
14064 }
14065
14066
14067
14068
14069
14070
14071 tree
14072 getdecls ()
14073 {
14074 return current_binding_level->names;
14075 }
14076
14077
14078
14079 int
14080 global_bindings_p ()
14081 {
14082 return current_binding_level == global_binding_level;
14083 }
14084
14085
14086
14087
14088
14089 void
14090 incomplete_type_error (value, type)
14091 tree value UNUSED;
14092 tree type;
14093 {
14094 if (TREE_CODE (type) == ERROR_MARK)
14095 return;
14096
14097 assert ("incomplete type?!?" == NULL);
14098 }
14099
14100
14101 static void
14102 mark_binding_level (void *arg)
14103 {
14104 struct binding_level *level = *(struct binding_level **) arg;
14105
14106 while (level)
14107 {
14108 ggc_mark_tree (level->names);
14109 ggc_mark_tree (level->blocks);
14110 ggc_mark_tree (level->this_block);
14111 level = level->level_chain;
14112 }
14113 }
14114
14115 static void
14116 ffecom_init_decl_processing ()
14117 {
14118 static tree *const tree_roots[] = {
14119 ¤t_function_decl,
14120 &string_type_node,
14121 &ffecom_tree_fun_type_void,
14122 &ffecom_integer_zero_node,
14123 &ffecom_integer_one_node,
14124 &ffecom_tree_subr_type,
14125 &ffecom_tree_ptr_to_subr_type,
14126 &ffecom_tree_blockdata_type,
14127 &ffecom_tree_xargc_,
14128 &ffecom_f2c_integer_type_node,
14129 &ffecom_f2c_ptr_to_integer_type_node,
14130 &ffecom_f2c_address_type_node,
14131 &ffecom_f2c_real_type_node,
14132 &ffecom_f2c_ptr_to_real_type_node,
14133 &ffecom_f2c_doublereal_type_node,
14134 &ffecom_f2c_complex_type_node,
14135 &ffecom_f2c_doublecomplex_type_node,
14136 &ffecom_f2c_longint_type_node,
14137 &ffecom_f2c_logical_type_node,
14138 &ffecom_f2c_flag_type_node,
14139 &ffecom_f2c_ftnlen_type_node,
14140 &ffecom_f2c_ftnlen_zero_node,
14141 &ffecom_f2c_ftnlen_one_node,
14142 &ffecom_f2c_ftnlen_two_node,
14143 &ffecom_f2c_ptr_to_ftnlen_type_node,
14144 &ffecom_f2c_ftnint_type_node,
14145 &ffecom_f2c_ptr_to_ftnint_type_node,
14146 &ffecom_outer_function_decl_,
14147 &ffecom_previous_function_decl_,
14148 &ffecom_which_entrypoint_decl_,
14149 &ffecom_float_zero_,
14150 &ffecom_float_half_,
14151 &ffecom_double_zero_,
14152 &ffecom_double_half_,
14153 &ffecom_func_result_,
14154 &ffecom_func_length_,
14155 &ffecom_multi_type_node_,
14156 &ffecom_multi_retval_,
14157 &named_labels,
14158 &shadowed_labels
14159 };
14160 size_t i;
14161
14162 malloc_init ();
14163
14164
14165 for (i = 0; i < ARRAY_SIZE (tree_roots); i++)
14166 ggc_add_tree_root (tree_roots[i], 1);
14167 ggc_add_tree_root (&ffecom_tree_type[0][0],
14168 FFEINFO_basictype*FFEINFO_kindtype);
14169 ggc_add_tree_root (&ffecom_tree_fun_type[0][0],
14170 FFEINFO_basictype*FFEINFO_kindtype);
14171 ggc_add_tree_root (&ffecom_tree_ptr_to_fun_type[0][0],
14172 FFEINFO_basictype*FFEINFO_kindtype);
14173 ggc_add_tree_root (ffecom_gfrt_, FFECOM_gfrt);
14174 ggc_add_root (¤t_binding_level, 1, sizeof current_binding_level,
14175 mark_binding_level);
14176 ggc_add_root (&free_binding_level, 1, sizeof current_binding_level,
14177 mark_binding_level);
14178 ggc_add_root (&tracker_head, 1, sizeof tracker_head, mark_tracker_head);
14179
14180 ffe_init_0 ();
14181 }
14182
14183
14184
14185
14186
14187 static void
14188 delete_block (block)
14189 tree block;
14190 {
14191 tree t;
14192 if (current_binding_level->blocks == block)
14193 current_binding_level->blocks = TREE_CHAIN (block);
14194 for (t = current_binding_level->blocks; t;)
14195 {
14196 if (TREE_CHAIN (t) == block)
14197 TREE_CHAIN (t) = TREE_CHAIN (block);
14198 else
14199 t = TREE_CHAIN (t);
14200 }
14201 TREE_CHAIN (block) = NULL;
14202
14203
14204 TREE_USED (block) = 0;
14205 }
14206
14207 void
14208 insert_block (block)
14209 tree block;
14210 {
14211 TREE_USED (block) = 1;
14212 current_binding_level->blocks
14213 = chainon (current_binding_level->blocks, block);
14214 }
14215
14216
14217 static const char *ffe_init PARAMS ((const char *));
14218 static void ffe_finish PARAMS ((void));
14219 static void ffe_init_options PARAMS ((void));
14220 static void ffe_print_identifier PARAMS ((FILE *, tree, int));
14221
14222 #undef LANG_HOOKS_NAME
14223 #define LANG_HOOKS_NAME "GNU F77"
14224 #undef LANG_HOOKS_INIT
14225 #define LANG_HOOKS_INIT ffe_init
14226 #undef LANG_HOOKS_FINISH
14227 #define LANG_HOOKS_FINISH ffe_finish
14228 #undef LANG_HOOKS_INIT_OPTIONS
14229 #define LANG_HOOKS_INIT_OPTIONS ffe_init_options
14230 #undef LANG_HOOKS_DECODE_OPTION
14231 #define LANG_HOOKS_DECODE_OPTION ffe_decode_option
14232 #undef LANG_HOOKS_PRINT_IDENTIFIER
14233 #define LANG_HOOKS_PRINT_IDENTIFIER ffe_print_identifier
14234
14235
14236
14237
14238
14239
14240 #undef LANG_HOOKS_GET_ALIAS_SET
14241 #define LANG_HOOKS_GET_ALIAS_SET hook_get_alias_set_0
14242
14243 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
14244
14245 static const char *
14246 ffe_init (filename)
14247 const char *filename;
14248 {
14249
14250 if (filename == 0 || !strcmp (filename, "-"))
14251 {
14252 finput = stdin;
14253 filename = "stdin";
14254 }
14255 else
14256 finput = fopen (filename, "r");
14257 if (finput == 0)
14258 fatal_io_error ("can't open %s", filename);
14259
14260 #ifdef IO_BUFFER_SIZE
14261 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
14262 #endif
14263
14264 ffecom_init_decl_processing ();
14265 decl_printable_name = lang_printable_name;
14266 print_error_function = lang_print_error_function;
14267
14268
14269
14270
14271
14272
14273
14274 ffelex_hash_kludge (finput);
14275
14276
14277
14278 if (main_input_filename)
14279 filename = main_input_filename;
14280
14281 return filename;
14282 }
14283
14284 static void
14285 ffe_finish ()
14286 {
14287 ffe_terminate_0 ();
14288
14289 if (ffe_is_ffedebug ())
14290 malloc_pool_display (malloc_pool_image ());
14291
14292 fclose (finput);
14293 }
14294
14295 static void
14296 ffe_init_options ()
14297 {
14298
14299 flag_move_all_movables = 1;
14300 flag_reduce_all_givs = 1;
14301 flag_argument_noalias = 2;
14302 flag_merge_constants = 2;
14303 flag_errno_math = 0;
14304 flag_complex_divide_method = 1;
14305 }
14306
14307 int
14308 mark_addressable (exp)
14309 tree exp;
14310 {
14311 register tree x = exp;
14312 while (1)
14313 switch (TREE_CODE (x))
14314 {
14315 case ADDR_EXPR:
14316 case COMPONENT_REF:
14317 case ARRAY_REF:
14318 x = TREE_OPERAND (x, 0);
14319 break;
14320
14321 case CONSTRUCTOR:
14322 TREE_ADDRESSABLE (x) = 1;
14323 return 1;
14324
14325 case VAR_DECL:
14326 case CONST_DECL:
14327 case PARM_DECL:
14328 case RESULT_DECL:
14329 if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
14330 && DECL_NONLOCAL (x))
14331 {
14332 if (TREE_PUBLIC (x))
14333 {
14334 assert ("address of global register var requested" == NULL);
14335 return 0;
14336 }
14337 assert ("address of register variable requested" == NULL);
14338 }
14339 else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
14340 {
14341 if (TREE_PUBLIC (x))
14342 {
14343 assert ("address of global register var requested" == NULL);
14344 return 0;
14345 }
14346 assert ("address of register var requested" == NULL);
14347 }
14348 put_var_into_stack (x);
14349
14350
14351 case FUNCTION_DECL:
14352 TREE_ADDRESSABLE (x) = 1;
14353 #if 0
14354 if (DECL_CONTEXT (x) == 0)
14355 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
14356 #endif
14357
14358 default:
14359 return 1;
14360 }
14361 }
14362
14363
14364
14365
14366 tree
14367 maybe_build_cleanup (decl)
14368 tree decl UNUSED;
14369 {
14370
14371 return NULL_TREE;
14372 }
14373
14374
14375
14376
14377
14378
14379
14380
14381
14382
14383
14384
14385
14386
14387
14388
14389 tree
14390 poplevel (keep, reverse, functionbody)
14391 int keep;
14392 int reverse;
14393 int functionbody;
14394 {
14395 register tree link;
14396
14397
14398 tree decls;
14399 tree subblocks = current_binding_level->blocks;
14400 tree block = 0;
14401 tree decl;
14402 int block_previously_created;
14403
14404
14405
14406
14407
14408 if (reverse)
14409 current_binding_level->names
14410 = decls = nreverse (current_binding_level->names);
14411 else
14412 decls = current_binding_level->names;
14413
14414
14415
14416
14417 for (decl = decls; decl; decl = TREE_CHAIN (decl))
14418 if (TREE_CODE (decl) == FUNCTION_DECL
14419 && ! TREE_ASM_WRITTEN (decl)
14420 && DECL_INITIAL (decl) != 0
14421 && TREE_ADDRESSABLE (decl))
14422 {
14423
14424
14425
14426
14427
14428
14429 if (DECL_ABSTRACT_ORIGIN (decl) != 0
14430 && DECL_ABSTRACT_ORIGIN (decl) != decl)
14431 TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
14432 else if (DECL_SAVED_INSNS (decl) != 0)
14433 {
14434 push_function_context ();
14435 output_inline_function (decl);
14436 pop_function_context ();
14437 }
14438 }
14439
14440
14441
14442
14443
14444 block = 0;
14445 block_previously_created = (current_binding_level->this_block != 0);
14446 if (block_previously_created)
14447 block = current_binding_level->this_block;
14448 else if (keep || functionbody)
14449 block = make_node (BLOCK);
14450 if (block != 0)
14451 {
14452 BLOCK_VARS (block) = decls;
14453 BLOCK_SUBBLOCKS (block) = subblocks;
14454 }
14455
14456
14457
14458 for (link = subblocks; link; link = TREE_CHAIN (link))
14459 BLOCK_SUPERCONTEXT (link) = block;
14460
14461
14462
14463 for (link = decls; link; link = TREE_CHAIN (link))
14464 {
14465 if (DECL_NAME (link) != 0)
14466 {
14467
14468
14469 if (DECL_EXTERNAL (link))
14470 {
14471 if (TREE_USED (link))
14472 TREE_USED (DECL_NAME (link)) = 1;
14473 if (TREE_ADDRESSABLE (link))
14474 TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
14475 }
14476 IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
14477 }
14478 }
14479
14480
14481
14482
14483
14484 if (functionbody)
14485 {
14486
14487
14488
14489
14490
14491 BLOCK_VARS (block) = 0;
14492 }
14493
14494
14495
14496 {
14497 register struct binding_level *level = current_binding_level;
14498 current_binding_level = current_binding_level->level_chain;
14499
14500 level->level_chain = free_binding_level;
14501 free_binding_level = level;
14502 }
14503
14504
14505 if (functionbody
14506 && current_function_decl != error_mark_node)
14507 DECL_INITIAL (current_function_decl) = block;
14508 else if (block)
14509 {
14510 if (!block_previously_created)
14511 current_binding_level->blocks
14512 = chainon (current_binding_level->blocks, block);
14513 }
14514
14515
14516
14517
14518
14519 else if (subblocks)
14520 current_binding_level->blocks
14521 = chainon (current_binding_level->blocks, subblocks);
14522
14523 if (block)
14524 TREE_USED (block) = 1;
14525 return block;
14526 }
14527
14528 static void
14529 ffe_print_identifier (file, node, indent)
14530 FILE *file;
14531 tree node;
14532 int indent;
14533 {
14534 print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
14535 print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
14536 }
14537
14538
14539
14540
14541
14542
14543
14544
14545
14546 tree
14547 pushdecl (x)
14548 tree x;
14549 {
14550 register tree t;
14551 register tree name = DECL_NAME (x);
14552 register struct binding_level *b = current_binding_level;
14553
14554 if ((TREE_CODE (x) == FUNCTION_DECL)
14555 && (DECL_INITIAL (x) == 0)
14556 && DECL_EXTERNAL (x))
14557 DECL_CONTEXT (x) = NULL_TREE;
14558 else
14559 DECL_CONTEXT (x) = current_function_decl;
14560
14561 if (name)
14562 {
14563 if (IDENTIFIER_INVENTED (name))
14564 {
14565 DECL_ARTIFICIAL (x) = 1;
14566 DECL_IN_SYSTEM_HEADER (x) = 1;
14567 }
14568
14569 t = lookup_name_current_level (name);
14570
14571 assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE));
14572
14573
14574
14575
14576 assert ((b == global_binding_level)
14577 || !ffecom_transform_only_dummies_
14578 || TREE_CODE (x) == PARM_DECL);
14579
14580 if ((t != NULL_TREE) && duplicate_decls (x, t))
14581 return t;
14582
14583
14584
14585
14586
14587
14588
14589
14590
14591
14592
14593
14594
14595
14596
14597
14598
14599
14600
14601
14602
14603
14604
14605
14606
14607
14608
14609
14610
14611
14612
14613
14614
14615
14616
14617
14618
14619
14620
14621
14622 if (TREE_CODE (x) == TYPE_DECL)
14623 {
14624 if (DECL_SOURCE_LINE (x) == 0)
14625 {
14626 if (TYPE_NAME (TREE_TYPE (x)) == 0)
14627 TYPE_NAME (TREE_TYPE (x)) = x;
14628 }
14629 else if (TREE_TYPE (x) != error_mark_node)
14630 {
14631 tree tt = TREE_TYPE (x);
14632
14633 tt = build_type_copy (tt);
14634 TYPE_NAME (tt) = x;
14635 TREE_TYPE (x) = tt;
14636 }
14637 }
14638
14639
14640
14641 if (b == global_binding_level)
14642 IDENTIFIER_GLOBAL_VALUE (name) = x;
14643 else
14644 IDENTIFIER_LOCAL_VALUE (name) = x;
14645 }
14646
14647
14648
14649 TREE_CHAIN (x) = b->names;
14650 b->names = x;
14651
14652 return x;
14653 }
14654
14655
14656
14657 static int
14658 kept_level_p ()
14659 {
14660 tree decl;
14661
14662 for (decl = current_binding_level->names;
14663 decl;
14664 decl = TREE_CHAIN (decl))
14665 {
14666 if (TREE_USED (decl) || TREE_CODE (decl) != VAR_DECL
14667 || (DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)))
14668
14669
14670
14671 return 1;
14672 }
14673 return 0;
14674 }
14675
14676
14677
14678
14679
14680 void
14681 pushlevel (tag_transparent)
14682 int tag_transparent;
14683 {
14684 register struct binding_level *newlevel = NULL_BINDING_LEVEL;
14685
14686 assert (! tag_transparent);
14687
14688 if (current_binding_level == global_binding_level)
14689 {
14690 named_labels = 0;
14691 }
14692
14693
14694
14695 if (free_binding_level)
14696 {
14697 newlevel = free_binding_level;
14698 free_binding_level = free_binding_level->level_chain;
14699 }
14700 else
14701 {
14702 newlevel = make_binding_level ();
14703 }
14704
14705
14706
14707
14708 *newlevel = clear_binding_level;
14709 newlevel->level_chain = current_binding_level;
14710 current_binding_level = newlevel;
14711 }
14712
14713
14714
14715
14716 void
14717 set_block (block)
14718 register tree block;
14719 {
14720 current_binding_level->this_block = block;
14721 current_binding_level->names = chainon (current_binding_level->names,
14722 BLOCK_VARS (block));
14723 current_binding_level->blocks = chainon (current_binding_level->blocks,
14724 BLOCK_SUBBLOCKS (block));
14725 }
14726
14727 tree
14728 signed_or_unsigned_type (unsignedp, type)
14729 int unsignedp;
14730 tree type;
14731 {
14732 tree type2;
14733
14734 if (! INTEGRAL_TYPE_P (type))
14735 return type;
14736 if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
14737 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
14738 if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
14739 return unsignedp ? unsigned_type_node : integer_type_node;
14740 if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
14741 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
14742 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
14743 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
14744 if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
14745 return (unsignedp ? long_long_unsigned_type_node
14746 : long_long_integer_type_node);
14747
14748 type2 = type_for_size (TYPE_PRECISION (type), unsignedp);
14749 if (type2 == NULL_TREE)
14750 return type;
14751
14752 return type2;
14753 }
14754
14755 tree
14756 signed_type (type)
14757 tree type;
14758 {
14759 tree type1 = TYPE_MAIN_VARIANT (type);
14760 ffeinfoKindtype kt;
14761 tree type2;
14762
14763 if (type1 == unsigned_char_type_node || type1 == char_type_node)
14764 return signed_char_type_node;
14765 if (type1 == unsigned_type_node)
14766 return integer_type_node;
14767 if (type1 == short_unsigned_type_node)
14768 return short_integer_type_node;
14769 if (type1 == long_unsigned_type_node)
14770 return long_integer_type_node;
14771 if (type1 == long_long_unsigned_type_node)
14772 return long_long_integer_type_node;
14773 #if 0
14774 if (type1 == unsigned_intDI_type_node)
14775 return intDI_type_node;
14776 if (type1 == unsigned_intSI_type_node)
14777 return intSI_type_node;
14778 if (type1 == unsigned_intHI_type_node)
14779 return intHI_type_node;
14780 if (type1 == unsigned_intQI_type_node)
14781 return intQI_type_node;
14782 #endif
14783
14784 type2 = type_for_size (TYPE_PRECISION (type1), 0);
14785 if (type2 != NULL_TREE)
14786 return type2;
14787
14788 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
14789 {
14790 type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
14791
14792 if (type1 == type2)
14793 return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
14794 }
14795
14796 return type;
14797 }
14798
14799
14800
14801
14802
14803
14804
14805
14806
14807
14808
14809
14810 tree
14811 truthvalue_conversion (expr)
14812 tree expr;
14813 {
14814 if (TREE_CODE (expr) == ERROR_MARK)
14815 return expr;
14816
14817 #if 0
14818
14819
14820 switch (TREE_CODE (TREE_TYPE (expr)))
14821 {
14822 case RECORD_TYPE:
14823 error ("struct type value used where scalar is required");
14824 return integer_zero_node;
14825
14826 case UNION_TYPE:
14827 error ("union type value used where scalar is required");
14828 return integer_zero_node;
14829
14830 case ARRAY_TYPE:
14831 error ("array type value used where scalar is required");
14832 return integer_zero_node;
14833
14834 default:
14835 break;
14836 }
14837 #endif
14838
14839 switch (TREE_CODE (expr))
14840 {
14841
14842
14843 #if 0
14844 case COMPONENT_REF:
14845
14846 if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1)))
14847 && TREE_UNSIGNED (TREE_OPERAND (expr, 1)))
14848 return expr;
14849 break;
14850 #endif
14851
14852 case EQ_EXPR:
14853
14854
14855 #if 0
14856 if (integer_zerop (TREE_OPERAND (expr, 1)))
14857 return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0);
14858 #endif
14859 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
14860 case TRUTH_ANDIF_EXPR:
14861 case TRUTH_ORIF_EXPR:
14862 case TRUTH_AND_EXPR:
14863 case TRUTH_OR_EXPR:
14864 case TRUTH_XOR_EXPR:
14865 TREE_TYPE (expr) = integer_type_node;
14866 return expr;
14867
14868 case ERROR_MARK:
14869 return expr;
14870
14871 case INTEGER_CST:
14872 return integer_zerop (expr) ? integer_zero_node : integer_one_node;
14873
14874 case REAL_CST:
14875 return real_zerop (expr) ? integer_zero_node : integer_one_node;
14876
14877 case ADDR_EXPR:
14878 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
14879 return build (COMPOUND_EXPR, integer_type_node,
14880 TREE_OPERAND (expr, 0), integer_one_node);
14881 else
14882 return integer_one_node;
14883
14884 case COMPLEX_EXPR:
14885 return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
14886 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
14887 integer_type_node,
14888 truthvalue_conversion (TREE_OPERAND (expr, 0)),
14889 truthvalue_conversion (TREE_OPERAND (expr, 1)));
14890
14891 case NEGATE_EXPR:
14892 case ABS_EXPR:
14893 case FLOAT_EXPR:
14894 case FFS_EXPR:
14895
14896 return truthvalue_conversion (TREE_OPERAND (expr, 0));
14897
14898 case LROTATE_EXPR:
14899 case RROTATE_EXPR:
14900
14901
14902 if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
14903 return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1),
14904 truthvalue_conversion (TREE_OPERAND (expr, 0)));
14905 else
14906 return truthvalue_conversion (TREE_OPERAND (expr, 0));
14907
14908 case COND_EXPR:
14909
14910 return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0),
14911 truthvalue_conversion (TREE_OPERAND (expr, 1)),
14912 truthvalue_conversion (TREE_OPERAND (expr, 2))));
14913
14914 case CONVERT_EXPR:
14915
14916
14917 if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
14918 || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
14919 break;
14920
14921 case NOP_EXPR:
14922
14923 if (TYPE_PRECISION (TREE_TYPE (expr))
14924 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
14925 return truthvalue_conversion (TREE_OPERAND (expr, 0));
14926 break;
14927
14928 case MINUS_EXPR:
14929
14930
14931 if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
14932 && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
14933 break;
14934
14935 case BIT_XOR_EXPR:
14936
14937
14938 if (TREE_TYPE (TREE_OPERAND (expr, 0))
14939 == TREE_TYPE (TREE_OPERAND (expr, 1)))
14940 return ffecom_2 (NE_EXPR, integer_type_node,
14941 TREE_OPERAND (expr, 0),
14942 TREE_OPERAND (expr, 1));
14943 return ffecom_2 (NE_EXPR, integer_type_node,
14944 TREE_OPERAND (expr, 0),
14945 fold (build1 (NOP_EXPR,
14946 TREE_TYPE (TREE_OPERAND (expr, 0)),
14947 TREE_OPERAND (expr, 1))));
14948
14949 case BIT_AND_EXPR:
14950 if (integer_onep (TREE_OPERAND (expr, 1)))
14951 return expr;
14952 break;
14953
14954 case MODIFY_EXPR:
14955 #if 0
14956 if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR)
14957 warning ("suggest parentheses around assignment used as truth value");
14958 #endif
14959 break;
14960
14961 default:
14962 break;
14963 }
14964
14965 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
14966 return (ffecom_2
14967 ((TREE_SIDE_EFFECTS (expr)
14968 ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
14969 integer_type_node,
14970 truthvalue_conversion (ffecom_1 (REALPART_EXPR,
14971 TREE_TYPE (TREE_TYPE (expr)),
14972 expr)),
14973 truthvalue_conversion (ffecom_1 (IMAGPART_EXPR,
14974 TREE_TYPE (TREE_TYPE (expr)),
14975 expr))));
14976
14977 return ffecom_2 (NE_EXPR, integer_type_node,
14978 expr,
14979 convert (TREE_TYPE (expr), integer_zero_node));
14980 }
14981
14982 tree
14983 type_for_mode (mode, unsignedp)
14984 enum machine_mode mode;
14985 int unsignedp;
14986 {
14987 int i;
14988 int j;
14989 tree t;
14990
14991 if (mode == TYPE_MODE (integer_type_node))
14992 return unsignedp ? unsigned_type_node : integer_type_node;
14993
14994 if (mode == TYPE_MODE (signed_char_type_node))
14995 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
14996
14997 if (mode == TYPE_MODE (short_integer_type_node))
14998 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
14999
15000 if (mode == TYPE_MODE (long_integer_type_node))
15001 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15002
15003 if (mode == TYPE_MODE (long_long_integer_type_node))
15004 return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
15005
15006 #if HOST_BITS_PER_WIDE_INT >= 64
15007 if (mode == TYPE_MODE (intTI_type_node))
15008 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
15009 #endif
15010
15011 if (mode == TYPE_MODE (float_type_node))
15012 return float_type_node;
15013
15014 if (mode == TYPE_MODE (double_type_node))
15015 return double_type_node;
15016
15017 if (mode == TYPE_MODE (long_double_type_node))
15018 return long_double_type_node;
15019
15020 if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
15021 return build_pointer_type (char_type_node);
15022
15023 if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
15024 return build_pointer_type (integer_type_node);
15025
15026 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
15027 for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
15028 {
15029 if (((t = ffecom_tree_type[i][j]) != NULL_TREE)
15030 && (mode == TYPE_MODE (t)))
15031 {
15032 if ((i == FFEINFO_basictypeINTEGER) && unsignedp)
15033 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j];
15034 else
15035 return t;
15036 }
15037 }
15038
15039 return 0;
15040 }
15041
15042 tree
15043 type_for_size (bits, unsignedp)
15044 unsigned bits;
15045 int unsignedp;
15046 {
15047 ffeinfoKindtype kt;
15048 tree type_node;
15049
15050 if (bits == TYPE_PRECISION (integer_type_node))
15051 return unsignedp ? unsigned_type_node : integer_type_node;
15052
15053 if (bits == TYPE_PRECISION (signed_char_type_node))
15054 return unsignedp ? unsigned_char_type_node : signed_char_type_node;
15055
15056 if (bits == TYPE_PRECISION (short_integer_type_node))
15057 return unsignedp ? short_unsigned_type_node : short_integer_type_node;
15058
15059 if (bits == TYPE_PRECISION (long_integer_type_node))
15060 return unsignedp ? long_unsigned_type_node : long_integer_type_node;
15061
15062 if (bits == TYPE_PRECISION (long_long_integer_type_node))
15063 return (unsignedp ? long_long_unsigned_type_node
15064 : long_long_integer_type_node);
15065
15066 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15067 {
15068 type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15069
15070 if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node)))
15071 return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]
15072 : type_node;
15073 }
15074
15075 return 0;
15076 }
15077
15078 tree
15079 unsigned_type (type)
15080 tree type;
15081 {
15082 tree type1 = TYPE_MAIN_VARIANT (type);
15083 ffeinfoKindtype kt;
15084 tree type2;
15085
15086 if (type1 == signed_char_type_node || type1 == char_type_node)
15087 return unsigned_char_type_node;
15088 if (type1 == integer_type_node)
15089 return unsigned_type_node;
15090 if (type1 == short_integer_type_node)
15091 return short_unsigned_type_node;
15092 if (type1 == long_integer_type_node)
15093 return long_unsigned_type_node;
15094 if (type1 == long_long_integer_type_node)
15095 return long_long_unsigned_type_node;
15096 #if 0
15097 if (type1 == intDI_type_node)
15098 return unsigned_intDI_type_node;
15099 if (type1 == intSI_type_node)
15100 return unsigned_intSI_type_node;
15101 if (type1 == intHI_type_node)
15102 return unsigned_intHI_type_node;
15103 if (type1 == intQI_type_node)
15104 return unsigned_intQI_type_node;
15105 #endif
15106
15107 type2 = type_for_size (TYPE_PRECISION (type1), 1);
15108 if (type2 != NULL_TREE)
15109 return type2;
15110
15111 for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt)
15112 {
15113 type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt];
15114
15115 if (type1 == type2)
15116 return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
15117 }
15118
15119 return type;
15120 }
15121
15122 void
15123 lang_mark_tree (t)
15124 union tree_node *t ATTRIBUTE_UNUSED;
15125 {
15126 if (TREE_CODE (t) == IDENTIFIER_NODE)
15127 {
15128 struct lang_identifier *i = (struct lang_identifier *) t;
15129 ggc_mark_tree (IDENTIFIER_GLOBAL_VALUE (i));
15130 ggc_mark_tree (IDENTIFIER_LOCAL_VALUE (i));
15131 ggc_mark_tree (IDENTIFIER_LABEL_VALUE (i));
15132 }
15133 else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
15134 ggc_mark (TYPE_LANG_SPECIFIC (t));
15135 }
15136
15137
15138
15139
15140
15141
15142 static const char *
15143 skip_redundant_dir_prefix (const char *dir)
15144 {
15145 while (dir[0] == '.' && dir[1] == '/')
15146 for (dir += 2; *dir == '/'; dir++)
15147 continue;
15148 if (dir[0] == '.' && !dir[1])
15149 dir++;
15150 return dir;
15151 }
15152
15153
15154
15155
15156
15157
15158
15159
15160
15161 struct file_name_map
15162 {
15163 struct file_name_map *map_next;
15164 char *map_from;
15165 char *map_to;
15166 };
15167
15168 #define FILE_NAME_MAP_FILE "header.gcc"
15169
15170
15171
15172
15173 static int max_include_len = 0;
15174
15175 struct file_name_list
15176 {
15177 struct file_name_list *next;
15178 char *fname;
15179
15180 struct file_name_map *name_map;
15181
15182 int got_name_map;
15183 };
15184
15185 static struct file_name_list *include = NULL;
15186 static struct file_name_list *last_include = NULL;
15187
15188
15189
15190
15191
15192
15193 #define INPUT_STACK_MAX 400
15194 static struct file_buf {
15195 const char *fname;
15196
15197 const char *nominal_fname;
15198
15199
15200 struct file_name_list *dir;
15201 ffewhereLine line;
15202 ffewhereColumn column;
15203 } instack[INPUT_STACK_MAX];
15204
15205 static int last_error_tick = 0;
15206 static int input_file_stack_tick = 0;
15207
15208
15209
15210 static int indepth = -1;
15211
15212 typedef struct file_buf FILE_BUF;
15213
15214
15215
15216 static int ignore_srcdir;
15217
15218 #ifndef INCLUDE_LEN_FUDGE
15219 #define INCLUDE_LEN_FUDGE 0
15220 #endif
15221
15222 static void append_include_chain (struct file_name_list *first,
15223 struct file_name_list *last);
15224 static FILE *open_include_file (char *filename,
15225 struct file_name_list *searchptr);
15226 static void print_containing_files (ffebadSeverity sev);
15227 static char *read_filename_string (int ch, FILE *f);
15228 static struct file_name_map *read_name_map (const char *dirname);
15229
15230
15231
15232
15233
15234 static void
15235 append_include_chain (first, last)
15236 struct file_name_list *first, *last;
15237 {
15238 struct file_name_list *dir;
15239
15240 if (!first || !last)
15241 return;
15242
15243 if (include == 0)
15244 include = first;
15245 else
15246 last_include->next = first;
15247
15248 for (dir = first; ; dir = dir->next) {
15249 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
15250 if (len > max_include_len)
15251 max_include_len = len;
15252 if (dir == last)
15253 break;
15254 }
15255
15256 last->next = NULL;
15257 last_include = last;
15258 }
15259
15260
15261
15262
15263
15264
15265 static FILE *
15266 open_include_file (filename, searchptr)
15267 char *filename;
15268 struct file_name_list *searchptr;
15269 {
15270 register struct file_name_map *map;
15271 register char *from;
15272 char *p, *dir;
15273
15274 if (searchptr && ! searchptr->got_name_map)
15275 {
15276 searchptr->name_map = read_name_map (searchptr->fname
15277 ? searchptr->fname : ".");
15278 searchptr->got_name_map = 1;
15279 }
15280
15281
15282 if (searchptr && searchptr->name_map)
15283 {
15284 from = filename;
15285 if (searchptr->fname)
15286 from += strlen (searchptr->fname) + 1;
15287 for (map = searchptr->name_map; map; map = map->map_next)
15288 {
15289 if (! strcmp (map->map_from, from))
15290 {
15291
15292 return fopen (map->map_to, "r");
15293 }
15294 }
15295 }
15296
15297
15298
15299
15300
15301 p = strrchr (filename, '/');
15302 #ifdef DIR_SEPARATOR
15303 if (! p) p = strrchr (filename, DIR_SEPARATOR);
15304 else {
15305 char *tmp = strrchr (filename, DIR_SEPARATOR);
15306 if (tmp != NULL && tmp > p) p = tmp;
15307 }
15308 #endif
15309 if (! p)
15310 p = filename;
15311 if (searchptr
15312 && searchptr->fname
15313 && strlen (searchptr->fname) == (size_t) (p - filename)
15314 && ! strncmp (searchptr->fname, filename, (int) (p - filename)))
15315 {
15316
15317 return fopen (filename, "r");
15318 }
15319
15320 if (p == filename)
15321 {
15322 from = filename;
15323 map = read_name_map (".");
15324 }
15325 else
15326 {
15327 dir = (char *) xmalloc (p - filename + 1);
15328 memcpy (dir, filename, p - filename);
15329 dir[p - filename] = '\0';
15330 from = p + 1;
15331 map = read_name_map (dir);
15332 free (dir);
15333 }
15334 for (; map; map = map->map_next)
15335 if (! strcmp (map->map_from, from))
15336 return fopen (map->map_to, "r");
15337
15338 return fopen (filename, "r");
15339 }
15340
15341
15342
15343
15344 static void
15345 print_containing_files (ffebadSeverity sev)
15346 {
15347 FILE_BUF *ip = NULL;
15348 int i;
15349 int first = 1;
15350 const char *str1;
15351 const char *str2;
15352
15353
15354
15355 if (last_error_tick == input_file_stack_tick)
15356 return;
15357
15358 for (i = indepth; i >= 0; i--)
15359 if (instack[i].fname != NULL) {
15360 ip = &instack[i];
15361 break;
15362 }
15363
15364
15365 if (ip == NULL)
15366 return;
15367
15368
15369 for (i--; i >= 0; i--)
15370 if (instack[i].fname != NULL)
15371 {
15372 ip = &instack[i];
15373 if (first)
15374 {
15375 first = 0;
15376 str1 = "In file included";
15377 }
15378 else
15379 {
15380 str1 = "... ...";
15381 }
15382
15383 if (i == 1)
15384 str2 = ":";
15385 else
15386 str2 = "";
15387
15388
15389 ffebad_start_msg ("%A from %B at %0%C", sev);
15390 ffebad_here (0, ip->line, ip->column);
15391 ffebad_string (str1);
15392 ffebad_string (ip->nominal_fname);
15393 ffebad_string (str2);
15394 ffebad_finish ();
15395 }
15396
15397
15398 last_error_tick = input_file_stack_tick;
15399 }
15400
15401
15402
15403
15404 static char *
15405 read_filename_string (ch, f)
15406 int ch;
15407 FILE *f;
15408 {
15409 char *alloc, *set;
15410 int len;
15411
15412 len = 20;
15413 set = alloc = xmalloc (len + 1);
15414 if (! ISSPACE (ch))
15415 {
15416 *set++ = ch;
15417 while ((ch = getc (f)) != EOF && ! ISSPACE (ch))
15418 {
15419 if (set - alloc == len)
15420 {
15421 len *= 2;
15422 alloc = xrealloc (alloc, len + 1);
15423 set = alloc + len / 2;
15424 }
15425 *set++ = ch;
15426 }
15427 }
15428 *set = '\0';
15429 ungetc (ch, f);
15430 return alloc;
15431 }
15432
15433
15434
15435 static struct file_name_map *
15436 read_name_map (dirname)
15437 const char *dirname;
15438 {
15439
15440
15441 struct file_name_map_list
15442 {
15443 struct file_name_map_list *map_list_next;
15444 char *map_list_name;
15445 struct file_name_map *map_list_map;
15446 };
15447 static struct file_name_map_list *map_list;
15448 register struct file_name_map_list *map_list_ptr;
15449 char *name;
15450 FILE *f;
15451 size_t dirlen;
15452 int separator_needed;
15453
15454 dirname = skip_redundant_dir_prefix (dirname);
15455
15456 for (map_list_ptr = map_list; map_list_ptr;
15457 map_list_ptr = map_list_ptr->map_list_next)
15458 if (! strcmp (map_list_ptr->map_list_name, dirname))
15459 return map_list_ptr->map_list_map;
15460
15461 map_list_ptr = ((struct file_name_map_list *)
15462 xmalloc (sizeof (struct file_name_map_list)));
15463 map_list_ptr->map_list_name = xstrdup (dirname);
15464 map_list_ptr->map_list_map = NULL;
15465
15466 dirlen = strlen (dirname);
15467 separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/';
15468 name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2);
15469 strcpy (name, dirname);
15470 name[dirlen] = '/';
15471 strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE);
15472 f = fopen (name, "r");
15473 free (name);
15474 if (!f)
15475 map_list_ptr->map_list_map = NULL;
15476 else
15477 {
15478 int ch;
15479
15480 while ((ch = getc (f)) != EOF)
15481 {
15482 char *from, *to;
15483 struct file_name_map *ptr;
15484
15485 if (ISSPACE (ch))
15486 continue;
15487 from = read_filename_string (ch, f);
15488 while ((ch = getc (f)) != EOF && ISSPACE (ch) && ch != '\n')
15489 ;
15490 to = read_filename_string (ch, f);
15491
15492 ptr = ((struct file_name_map *)
15493 xmalloc (sizeof (struct file_name_map)));
15494 ptr->map_from = from;
15495
15496
15497 if (*to == '/')
15498 ptr->map_to = to;
15499 else
15500 {
15501 ptr->map_to = xmalloc (dirlen + strlen (to) + 2);
15502 strcpy (ptr->map_to, dirname);
15503 ptr->map_to[dirlen] = '/';
15504 strcpy (ptr->map_to + dirlen + separator_needed, to);
15505 free (to);
15506 }
15507
15508 ptr->map_next = map_list_ptr->map_list_map;
15509 map_list_ptr->map_list_map = ptr;
15510
15511 while ((ch = getc (f)) != '\n')
15512 if (ch == EOF)
15513 break;
15514 }
15515 fclose (f);
15516 }
15517
15518 map_list_ptr->map_list_next = map_list;
15519 map_list = map_list_ptr;
15520
15521 return map_list_ptr->map_list_map;
15522 }
15523
15524 static void
15525 ffecom_file_ (const char *name)
15526 {
15527 FILE_BUF *fp;
15528
15529
15530
15531
15532 fp = &instack[++indepth];
15533 memset ((char *) fp, 0, sizeof (FILE_BUF));
15534 if (name == NULL)
15535 name = "";
15536 fp->nominal_fname = fp->fname = name;
15537 }
15538
15539 static void
15540 ffecom_close_include_ (FILE *f)
15541 {
15542 fclose (f);
15543
15544 indepth--;
15545 input_file_stack_tick++;
15546
15547 ffewhere_line_kill (instack[indepth].line);
15548 ffewhere_column_kill (instack[indepth].column);
15549 }
15550
15551 static int
15552 ffecom_decode_include_option_ (char *spec)
15553 {
15554 struct file_name_list *dirtmp;
15555
15556 if (! ignore_srcdir && !strcmp (spec, "-"))
15557 ignore_srcdir = 1;
15558 else
15559 {
15560 dirtmp = (struct file_name_list *)
15561 xmalloc (sizeof (struct file_name_list));
15562 dirtmp->next = 0;
15563 dirtmp->fname = spec;
15564 dirtmp->got_name_map = 0;
15565 if (spec[0] == 0)
15566 error ("directory name must immediately follow -I");
15567 else
15568 append_include_chain (dirtmp, dirtmp);
15569 }
15570 return 1;
15571 }
15572
15573
15574
15575 static FILE *
15576 ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
15577 {
15578 char *fbeg = name;
15579 size_t flen = strlen (fbeg);
15580 struct file_name_list *search_start = include;
15581 struct file_name_list dsp[1];
15582 struct file_name_list *searchptr = 0;
15583 char *fname;
15584 FILE *f;
15585 FILE_BUF *fp;
15586
15587 if (flen == 0)
15588 return NULL;
15589
15590 dsp[0].fname = NULL;
15591
15592
15593 if (!ignore_srcdir)
15594 {
15595 for (fp = &instack[indepth]; fp >= instack; fp--)
15596 {
15597 int n;
15598 char *ep;
15599 const char *nam;
15600
15601 if ((nam = fp->nominal_fname) != NULL)
15602 {
15603
15604
15605 dsp[0].next = search_start;
15606 search_start = dsp;
15607 #ifndef VMS
15608 ep = strrchr (nam, '/');
15609 #ifdef DIR_SEPARATOR
15610 if (ep == NULL) ep = strrchr (nam, DIR_SEPARATOR);
15611 else {
15612 char *tmp = strrchr (nam, DIR_SEPARATOR);
15613 if (tmp != NULL && tmp > ep) ep = tmp;
15614 }
15615 #endif
15616 #else
15617 ep = strrchr (nam, ']');
15618 if (ep == NULL) ep = strrchr (nam, '>');
15619 if (ep == NULL) ep = strrchr (nam, ':');
15620 if (ep != NULL) ep++;
15621 #endif
15622 if (ep != NULL)
15623 {
15624 n = ep - nam;
15625 dsp[0].fname = (char *) xmalloc (n + 1);
15626 strncpy (dsp[0].fname, nam, n);
15627 dsp[0].fname[n] = '\0';
15628 if (n + INCLUDE_LEN_FUDGE > max_include_len)
15629 max_include_len = n + INCLUDE_LEN_FUDGE;
15630 }
15631 else
15632 dsp[0].fname = NULL;
15633 dsp[0].got_name_map = 0;
15634 break;
15635 }
15636 }
15637 }
15638
15639
15640
15641 fname = xmalloc (max_include_len + flen + 4);
15642
15643
15644
15645
15646
15647
15648 if (*fbeg == '/'
15649 #ifdef DIR_SEPARATOR
15650 || *fbeg == DIR_SEPARATOR
15651 #endif
15652 )
15653 {
15654 strncpy (fname, (char *) fbeg, flen);
15655 fname[flen] = 0;
15656 f = open_include_file (fname, NULL);
15657 }
15658 else
15659 {
15660 f = NULL;
15661
15662
15663
15664
15665 for (searchptr = search_start; searchptr; searchptr = searchptr->next)
15666 {
15667 if (searchptr->fname)
15668 {
15669
15670
15671
15672 if (searchptr->fname[0] == 0)
15673 continue;
15674 strcpy (fname, skip_redundant_dir_prefix (searchptr->fname));
15675 if (fname[0] && fname[strlen (fname) - 1] != '/')
15676 strcat (fname, "/");
15677 fname[strlen (fname) + flen] = 0;
15678 }
15679 else
15680 fname[0] = 0;
15681
15682 strncat (fname, fbeg, flen);
15683 #ifdef VMS
15684
15685
15686 if (searchptr->fname && (searchptr->fname[0] != 0))
15687 {
15688
15689 hack_vms_include_specification (fname);
15690 }
15691 else
15692 {
15693
15694 strncpy (fname, (char *) fbeg, flen);
15695 fname[flen] = 0;
15696 #if 0
15697
15698 if (strchr (fname, '.') == NULL)
15699 strcat (fname, ".h");
15700 #endif
15701 }
15702 #endif
15703 f = open_include_file (fname, searchptr);
15704 #ifdef EACCES
15705 if (f == NULL && errno == EACCES)
15706 {
15707 print_containing_files (FFEBAD_severityWARNING);
15708
15709 ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable",
15710 FFEBAD_severityWARNING);
15711 ffebad_string (fname);
15712 ffebad_here (0, l, c);
15713 ffebad_finish ();
15714 }
15715 #endif
15716 if (f != NULL)
15717 break;
15718 }
15719 }
15720
15721 if (f == NULL)
15722 {
15723
15724
15725 strncpy (fname, (char *) fbeg, flen);
15726 fname[flen] = 0;
15727 print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE));
15728 ffebad_start (FFEBAD_OPEN_INCLUDE);
15729 ffebad_here (0, l, c);
15730 ffebad_string (fname);
15731 ffebad_finish ();
15732 }
15733
15734 if (dsp[0].fname != NULL)
15735 free (dsp[0].fname);
15736
15737 if (f == NULL)
15738 return NULL;
15739
15740 if (indepth >= (INPUT_STACK_MAX - 1))
15741 {
15742 print_containing_files (FFEBAD_severityFATAL);
15743
15744 ffebad_start_msg ("At %0, INCLUDE nesting too deep",
15745 FFEBAD_severityFATAL);
15746 ffebad_string (fname);
15747 ffebad_here (0, l, c);
15748 ffebad_finish ();
15749 return NULL;
15750 }
15751
15752 instack[indepth].line = ffewhere_line_use (l);
15753 instack[indepth].column = ffewhere_column_use (c);
15754
15755 fp = &instack[indepth + 1];
15756 memset ((char *) fp, 0, sizeof (FILE_BUF));
15757 fp->nominal_fname = fp->fname = fname;
15758 fp->dir = searchptr;
15759
15760 indepth++;
15761 input_file_stack_tick++;
15762
15763 return f;
15764 }
15765
16023