1 /* intrin.c -- Recognize references to intrinsics
2 Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
3 Contributed by James Craig Burley.
5 This file is part of GNU Fortran.
7 GNU Fortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Fortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Fortran; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
33 struct _ffeintrin_name_
35 const char *const name_uc;
36 const char *const name_lc;
37 const char *const name_ic;
38 const ffeintrinGen generic;
39 const ffeintrinSpec specific;
42 struct _ffeintrin_gen_
44 const char *const name; /* Name as seen in program. */
45 const ffeintrinSpec specs[2];
48 struct _ffeintrin_spec_
50 const char *const name; /* Uppercase name as seen in source code,
51 lowercase if no source name, "none" if no
52 name at all (NONE case). */
53 const bool is_actualarg; /* Ok to pass as actual arg if -pedantic. */
54 const ffeintrinFamily family;
55 const ffeintrinImp implementation;
58 struct _ffeintrin_imp_
60 const char *const name; /* Name of implementation. */
61 const ffecomGfrt gfrt_direct;/* library routine, direct-callable form. */
62 const ffecomGfrt gfrt_f2c; /* library routine, f2c-callable form. */
63 const ffecomGfrt gfrt_gnu; /* library routine, gnu-callable form. */
64 const char *const control;
68 static ffebad ffeintrin_check_ (ffeintrinImp imp, ffebldOp op,
69 ffebld args, ffeinfoBasictype *xbt,
71 ffetargetCharacterSize *xsz,
75 static bool ffeintrin_check_any_ (ffebld arglist);
76 static int ffeintrin_cmp_name_ (const void *name, const void *intrinsic);
78 static const struct _ffeintrin_name_ ffeintrin_names_[]
81 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) \
82 { UPPER, LOWER, MIXED, FFEINTRIN_ ## GEN, FFEINTRIN_ ## SPEC },
83 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
84 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
85 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
86 #define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
95 static const struct _ffeintrin_gen_ ffeintrin_gens_[]
98 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
99 #define DEFGEN(CODE,NAME,SPEC1,SPEC2) \
100 { NAME, { SPEC1, SPEC2, }, },
101 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
102 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
103 #define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
104 #include "intrin.def"
112 static const struct _ffeintrin_imp_ ffeintrin_imps_[]
115 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
116 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
117 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
118 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \
119 { NAME, FFECOM_gfrt ## GFRTDIRECT, FFECOM_gfrt ## GFRTF2C, \
120 FFECOM_gfrt ## GFRTGNU, CONTROL, FALSE },
121 #define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD) \
122 { NAME, FFECOM_gfrt ## GFRTDIRECT, FFECOM_gfrt ## GFRTF2C, \
123 FFECOM_gfrt ## GFRTGNU, CONTROL, Y2KBAD },
124 #include "intrin.def"
132 static const struct _ffeintrin_spec_ ffeintrin_specs_[]
135 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
136 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
137 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) \
138 { NAME, CALLABLE, FAMILY, IMP, },
139 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
140 #define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
141 #include "intrin.def"
150 ffeintrin_check_ (ffeintrinImp imp, ffebldOp op,
151 ffebld args, ffeinfoBasictype *xbt,
152 ffeinfoKindtype *xkt,
153 ffetargetCharacterSize *xsz,
158 const char *c = ffeintrin_imps_[imp].control;
159 bool subr = (c[0] == '-');
164 ffetargetCharacterSize sz = FFETARGET_charactersizeNONE;
165 ffeinfoKindtype firstarg_kt;
167 ffeinfoBasictype col_bt = FFEINFO_basictypeNONE;
168 ffeinfoKindtype col_kt = FFEINFO_kindtypeNONE;
169 int colon = (c[2] == ':') ? 2 : 3;
172 /* Check procedure type (function vs. subroutine) against
175 if (op == FFEBLD_opSUBRREF)
178 return FFEBAD_INTRINSIC_IS_FUNC;
180 else if (op == FFEBLD_opFUNCREF)
183 return FFEBAD_INTRINSIC_IS_SUBR;
186 return FFEBAD_INTRINSIC_REF;
188 /* Check the arglist for validity. */
191 && (ffebld_head (args) != NULL))
192 firstarg_kt = ffeinfo_kindtype (ffebld_info (ffebld_head (args)));
194 firstarg_kt = FFEINFO_kindtype;
196 for (argc = &c[colon + 3],
201 char optional = '\0';
202 char required = '\0';
208 bool lastarg_complex = FALSE;
210 /* We don't do anything with keywords yet. */
213 } while (*(++argc) != '=');
219 optional = *(argc++);
223 required = *(argc++);
228 length = *++argc - '0';
230 length = 10 * length + (*(argc++) - '0');
237 elements = *++argc - '0';
239 elements = 10 * elements + (*(argc++) - '0');
242 else if (*argc == '&')
257 /* Break out of this loop only when current arg spec completely
266 ffeinfoBasictype abt = FFEINFO_basictypeNONE;
267 ffeinfoKindtype akt = FFEINFO_kindtypeNONE;
270 || (ffebld_head (arg) == NULL))
272 if (required != '\0')
273 return FFEBAD_INTRINSIC_TOOFEW;
274 if (optional == '\0')
275 return FFEBAD_INTRINSIC_TOOFEW;
277 arg = ffebld_trail (arg);
278 break; /* Try next argspec. */
281 a = ffebld_head (arg);
283 anynum = (ffeinfo_basictype (i) == FFEINFO_basictypeHOLLERITH)
284 || (ffeinfo_basictype (i) == FFEINFO_basictypeTYPELESS);
286 /* See how well the arg matches up to the spec. */
291 okay = (ffeinfo_basictype (i) == FFEINFO_basictypeCHARACTER)
293 || (ffeinfo_size (i) == (ffetargetCharacterSize) length));
298 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX);
299 abt = FFEINFO_basictypeCOMPLEX;
304 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER);
305 abt = FFEINFO_basictypeINTEGER;
310 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL);
311 abt = FFEINFO_basictypeLOGICAL;
316 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
317 abt = FFEINFO_basictypeREAL;
322 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
323 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL);
328 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX)
329 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
334 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX)
335 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
336 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
341 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
342 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
346 okay = ((ffebld_op (a) == FFEBLD_opLABTER)
347 || (ffebld_op (a) == FFEBLD_opLABTOK));
353 okay = (((((ffeinfo_basictype (i) == FFEINFO_basictypeNONE)
354 && (ffeinfo_kindtype (i) == FFEINFO_kindtypeNONE)
355 && (ffeinfo_kind (i) == FFEINFO_kindSUBROUTINE))
356 || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
357 && (ffeinfo_kindtype (i) == FFEINFO_kindtypeINTEGERDEFAULT)
358 && (ffeinfo_kind (i) == FFEINFO_kindFUNCTION))
359 || (ffeinfo_kind (i) == FFEINFO_kindNONE))
360 && ((ffeinfo_where (i) == FFEINFO_whereDUMMY)
361 || (ffeinfo_where (i) == FFEINFO_whereGLOBAL)))
362 || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
363 && (ffeinfo_kind (i) == FFEINFO_kindENTITY)));
376 case '1': case '2': case '3': case '4': case '5':
377 case '6': case '7': case '8': case '9':
379 if ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
380 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL))
383 { /* Translate to internal kinds for now! */
404 akt = ffecom_pointer_kind ();
408 okay &= anynum || (ffeinfo_kindtype (i) == akt);
412 okay &= anynum || (ffeinfo_kindtype (i) == firstarg_kt);
413 akt = (firstarg_kt == FFEINFO_kindtype) ? FFEINFO_kindtypeNONE
430 if (ffeinfo_rank (i) != 0)
435 if ((ffeinfo_rank (i) != 1)
436 || (ffebld_op (a) != FFEBLD_opSYMTER)
437 || ((b = ffesymbol_arraysize (ffebld_symter (a))) == NULL)
438 || (ffebld_op (b) != FFEBLD_opCONTER)
439 || (ffeinfo_basictype (ffebld_info (b)) != FFEINFO_basictypeINTEGER)
440 || (ffeinfo_kindtype (ffebld_info (b)) != FFEINFO_kindtypeINTEGERDEFAULT)
441 || (ffebld_constant_integer1 (ffebld_conter (b)) != elements))
449 if ((ffeinfo_kind (i) != FFEINFO_kindENTITY)
450 || ((ffebld_op (a) != FFEBLD_opSYMTER)
451 && (ffebld_op (a) != FFEBLD_opSUBSTR)
452 && (ffebld_op (a) != FFEBLD_opARRAYREF)))
458 if ((ffeinfo_kind (i) != FFEINFO_kindENTITY)
459 || ((ffebld_op (a) != FFEBLD_opSYMTER)
460 && (ffebld_op (a) != FFEBLD_opARRAYREF)
461 && (ffebld_op (a) != FFEBLD_opSUBSTR)))
470 if (ffeinfo_kind (i) != FFEINFO_kindENTITY)
475 if ((optional == '!')
481 /* If it wasn't optional, it's an error,
482 else maybe it could match a later argspec. */
483 if (optional == '\0')
484 return FFEBAD_INTRINSIC_REF;
485 break; /* Try next argspec. */
489 = (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX);
493 /* If we know dummy arg type, convert to that now. */
495 if ((abt != FFEINFO_basictypeNONE)
496 && (akt != FFEINFO_kindtypeNONE)
499 /* We have a known type, convert hollerith/typeless
502 a = ffeexpr_convert (a, t, NULL,
504 FFETARGET_charactersizeNONE,
506 ffebld_set_head (arg, a);
510 arg = ffebld_trail (arg); /* Arg accepted, now move on. */
513 continue; /* Go ahead and try another arg. */
514 if (required == '\0')
516 if ((required == 'n')
517 || (required == '+'))
522 else if (required == 'p')
528 return FFEBAD_INTRINSIC_TOOMANY;
530 /* Set up the initial type for the return value of the function. */
536 bt = FFEINFO_basictypeCHARACTER;
537 sz = (c[2] == '*') ? FFETARGET_charactersizeNONE : 1;
541 bt = FFEINFO_basictypeCOMPLEX;
545 bt = FFEINFO_basictypeINTEGER;
549 bt = FFEINFO_basictypeLOGICAL;
553 bt = FFEINFO_basictypeREAL;
564 bt = FFEINFO_basictypeNONE;
570 case '1': case '2': case '3': case '4': case '5':
571 case '6': case '7': case '8': case '9':
573 if ((bt == FFEINFO_basictypeINTEGER)
574 || (bt == FFEINFO_basictypeLOGICAL))
577 { /* Translate to internal kinds for now! */
598 kt = ffecom_pointer_kind ();
615 kt = FFEINFO_kindtypeNONE;
619 /* Determine collective type of COL, if there is one. */
621 if (need_col || c[colon + 1] != '-')
624 bool have_anynum = FALSE;
628 arg = (c[colon + 1] == '*') ? ffebld_trail (arg) : NULL)
630 ffebld a = ffebld_head (arg);
638 anynum = (ffeinfo_basictype (i) == FFEINFO_basictypeHOLLERITH)
639 || (ffeinfo_basictype (i) == FFEINFO_basictypeTYPELESS);
646 if ((col_bt == FFEINFO_basictypeNONE)
647 && (col_kt == FFEINFO_kindtypeNONE))
649 col_bt = ffeinfo_basictype (i);
650 col_kt = ffeinfo_kindtype (i);
654 ffeexpr_type_combine (&col_bt, &col_kt,
656 ffeinfo_basictype (i),
657 ffeinfo_kindtype (i),
659 if ((col_bt == FFEINFO_basictypeNONE)
660 || (col_kt == FFEINFO_kindtypeNONE))
661 return FFEBAD_INTRINSIC_REF;
666 && ((col_bt == FFEINFO_basictypeNONE)
667 || (col_kt == FFEINFO_kindtypeNONE)))
669 /* No type, but have hollerith/typeless. Use type of return
670 value to determine type of COL. */
675 return FFEBAD_INTRINSIC_REF;
680 if ((col_bt != FFEINFO_basictypeNONE)
681 && (col_bt != FFEINFO_basictypeINTEGER))
682 return FFEBAD_INTRINSIC_REF;
688 col_bt = FFEINFO_basictypeINTEGER;
689 col_kt = FFEINFO_kindtypeINTEGER1;
693 if ((col_bt != FFEINFO_basictypeNONE)
694 && (col_bt != FFEINFO_basictypeCOMPLEX))
695 return FFEBAD_INTRINSIC_REF;
696 col_bt = FFEINFO_basictypeCOMPLEX;
697 col_kt = FFEINFO_kindtypeREAL1;
701 if ((col_bt != FFEINFO_basictypeNONE)
702 && (col_bt != FFEINFO_basictypeREAL))
703 return FFEBAD_INTRINSIC_REF;
706 col_bt = FFEINFO_basictypeREAL;
707 col_kt = FFEINFO_kindtypeREAL1;
715 okay = (col_bt == FFEINFO_basictypeINTEGER)
716 || (col_bt == FFEINFO_basictypeLOGICAL);
722 okay = (col_bt == FFEINFO_basictypeCOMPLEX)
723 || (col_bt == FFEINFO_basictypeREAL);
729 okay = (col_bt == FFEINFO_basictypeCOMPLEX)
730 || (col_bt == FFEINFO_basictypeINTEGER)
731 || (col_bt == FFEINFO_basictypeREAL);
737 okay = (col_bt == FFEINFO_basictypeINTEGER)
738 || (col_bt == FFEINFO_basictypeREAL)
739 || (col_bt == FFEINFO_basictypeCOMPLEX);
741 bt = ((col_bt != FFEINFO_basictypeCOMPLEX) ? col_bt
742 : FFEINFO_basictypeREAL);
754 if (col_bt == FFEINFO_basictypeCOMPLEX)
756 if (col_kt != FFEINFO_kindtypeREALDEFAULT)
757 *check_intrin = TRUE;
765 return FFEBAD_INTRINSIC_REF;
768 /* Now, convert args in the arglist to the final type of the COL. */
770 for (argno = 0, argc = &c[colon + 3],
775 char optional = '\0';
776 char required = '\0';
782 bool lastarg_complex = FALSE;
784 /* We don't do anything with keywords yet. */
787 } while (*(++argc) != '=');
793 optional = *(argc++);
797 required = *(argc++);
802 length = *++argc - '0';
804 length = 10 * length + (*(argc++) - '0');
811 elements = *++argc - '0';
813 elements = 10 * elements + (*(argc++) - '0');
816 else if (*argc == '&')
831 /* Break out of this loop only when current arg spec completely
840 ffeinfoBasictype abt = FFEINFO_basictypeNONE;
841 ffeinfoKindtype akt = FFEINFO_kindtypeNONE;
844 || (ffebld_head (arg) == NULL))
847 arg = ffebld_trail (arg);
848 break; /* Try next argspec. */
851 a = ffebld_head (arg);
853 anynum = (ffeinfo_basictype (i) == FFEINFO_basictypeHOLLERITH)
854 || (ffeinfo_basictype (i) == FFEINFO_basictypeTYPELESS);
856 /* Determine what the default type for anynum would be. */
860 switch (c[colon + 1])
864 case '0': case '1': case '2': case '3': case '4':
865 case '5': case '6': case '7': case '8': case '9':
866 if (argno != (c[colon + 1] - '0'))
875 /* Again, match arg up to the spec. We go through all of
876 this again to properly follow the contour of optional
877 arguments. Probably this level of flexibility is not
878 needed, perhaps it's even downright naughty. */
883 okay = (ffeinfo_basictype (i) == FFEINFO_basictypeCHARACTER)
885 || (ffeinfo_size (i) == (ffetargetCharacterSize) length));
890 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX);
891 abt = FFEINFO_basictypeCOMPLEX;
896 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER);
897 abt = FFEINFO_basictypeINTEGER;
902 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL);
903 abt = FFEINFO_basictypeLOGICAL;
908 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
909 abt = FFEINFO_basictypeREAL;
914 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
915 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL);
920 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX)
921 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
926 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX)
927 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
928 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
933 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
934 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
938 okay = ((ffebld_op (a) == FFEBLD_opLABTER)
939 || (ffebld_op (a) == FFEBLD_opLABTOK));
945 okay = (((((ffeinfo_basictype (i) == FFEINFO_basictypeNONE)
946 && (ffeinfo_kindtype (i) == FFEINFO_kindtypeNONE)
947 && (ffeinfo_kind (i) == FFEINFO_kindSUBROUTINE))
948 || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
949 && (ffeinfo_kindtype (i) == FFEINFO_kindtypeINTEGERDEFAULT)
950 && (ffeinfo_kind (i) == FFEINFO_kindFUNCTION))
951 || (ffeinfo_kind (i) == FFEINFO_kindNONE))
952 && ((ffeinfo_where (i) == FFEINFO_whereDUMMY)
953 || (ffeinfo_where (i) == FFEINFO_whereGLOBAL)))
954 || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
955 && (ffeinfo_kind (i) == FFEINFO_kindENTITY)));
968 case '1': case '2': case '3': case '4': case '5':
969 case '6': case '7': case '8': case '9':
971 if ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
972 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL))
975 { /* Translate to internal kinds for now! */
996 akt = ffecom_pointer_kind ();
1000 okay &= anynum || (ffeinfo_kindtype (i) == akt);
1004 okay &= anynum || (ffeinfo_kindtype (i) == firstarg_kt);
1005 akt = (firstarg_kt == FFEINFO_kindtype) ? FFEINFO_kindtypeNONE
1022 if (ffeinfo_rank (i) != 0)
1027 if ((ffeinfo_rank (i) != 1)
1028 || (ffebld_op (a) != FFEBLD_opSYMTER)
1029 || ((b = ffesymbol_arraysize (ffebld_symter (a))) == NULL)
1030 || (ffebld_op (b) != FFEBLD_opCONTER)
1031 || (ffeinfo_basictype (ffebld_info (b)) != FFEINFO_basictypeINTEGER)
1032 || (ffeinfo_kindtype (ffebld_info (b)) != FFEINFO_kindtypeINTEGERDEFAULT)
1033 || (ffebld_constant_integer1 (ffebld_conter (b)) != elements))
1041 if ((ffeinfo_kind (i) != FFEINFO_kindENTITY)
1042 || ((ffebld_op (a) != FFEBLD_opSYMTER)
1043 && (ffebld_op (a) != FFEBLD_opSUBSTR)
1044 && (ffebld_op (a) != FFEBLD_opARRAYREF)))
1050 if ((ffeinfo_kind (i) != FFEINFO_kindENTITY)
1051 || ((ffebld_op (a) != FFEBLD_opSYMTER)
1052 && (ffebld_op (a) != FFEBLD_opARRAYREF)
1053 && (ffebld_op (a) != FFEBLD_opSUBSTR)))
1062 if (ffeinfo_kind (i) != FFEINFO_kindENTITY)
1067 if ((optional == '!')
1073 /* If it wasn't optional, it's an error,
1074 else maybe it could match a later argspec. */
1075 if (optional == '\0')
1076 return FFEBAD_INTRINSIC_REF;
1077 break; /* Try next argspec. */
1081 = (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX);
1083 if (anynum && commit)
1085 /* If we know dummy arg type, convert to that now. */
1087 if (abt == FFEINFO_basictypeNONE)
1088 abt = FFEINFO_basictypeINTEGER;
1089 if (akt == FFEINFO_kindtypeNONE)
1090 akt = FFEINFO_kindtypeINTEGER1;
1092 /* We have a known type, convert hollerith/typeless to it. */
1094 a = ffeexpr_convert (a, t, NULL,
1096 FFETARGET_charactersizeNONE,
1097 FFEEXPR_contextLET);
1098 ffebld_set_head (arg, a);
1100 else if ((c[colon + 1] == '*') && commit)
1102 /* This is where we promote types to the consensus
1103 type for the COL. Maybe this is where -fpedantic
1104 should issue a warning as well. */
1106 a = ffeexpr_convert (a, t, NULL,
1109 FFEEXPR_contextLET);
1110 ffebld_set_head (arg, a);
1113 arg = ffebld_trail (arg); /* Arg accepted, now move on. */
1115 if (optional == '*')
1116 continue; /* Go ahead and try another arg. */
1117 if (required == '\0')
1119 if ((required == 'n')
1120 || (required == '+'))
1125 else if (required == 'p')
1137 ffeintrin_check_any_ (ffebld arglist)
1141 for (; arglist != NULL; arglist = ffebld_trail (arglist))
1143 item = ffebld_head (arglist);
1145 && (ffebld_op (item) == FFEBLD_opANY))
1152 /* Compare name to intrinsic's name. Uses strcmp on arguments' names. */
1155 ffeintrin_cmp_name_ (const void *name, const void *intrinsic)
1157 const char *const uc = ((const struct _ffeintrin_name_ *) intrinsic)->name_uc;
1158 const char *const lc = ((const struct _ffeintrin_name_ *) intrinsic)->name_lc;
1159 const char *const ic = ((const struct _ffeintrin_name_ *) intrinsic)->name_ic;
1161 return ffesrc_strcmp_2c (ffe_case_intrin (), name, uc, lc, ic);
1164 /* Return basic type of intrinsic implementation, based on its
1165 run-time implementation *only*. (This is used only when
1166 the type of an intrinsic name is needed without having a
1167 list of arguments, i.e. an interface signature, such as when
1168 passing the intrinsic itself, or really the run-time-library
1169 function, as an argument.)
1171 If there's no eligible intrinsic implementation, there must be
1172 a bug somewhere else; no such reference should have been permitted
1173 to go this far. (Well, this might be wrong.) */
1176 ffeintrin_basictype (ffeintrinSpec spec)
1181 assert (spec < FFEINTRIN_spec);
1182 imp = ffeintrin_specs_[spec].implementation;
1183 assert (imp < FFEINTRIN_imp);
1186 gfrt = ffeintrin_imps_[imp].gfrt_f2c;
1188 gfrt = ffeintrin_imps_[imp].gfrt_gnu;
1190 assert (gfrt != FFECOM_gfrt);
1192 return ffecom_gfrt_basictype (gfrt);
1195 /* Return family to which specific intrinsic belongs. */
1198 ffeintrin_family (ffeintrinSpec spec)
1200 if (spec >= FFEINTRIN_spec)
1202 return ffeintrin_specs_[spec].family;
1205 /* Check and fill in info on func/subr ref node.
1207 ffebld expr; // FUNCREF or SUBRREF with no info (caller
1208 // gets it from the modified info structure).
1209 ffeinfo info; // Already filled in, will be overwritten.
1210 ffelexToken token; // Used for error message.
1211 ffeintrin_fulfill_generic (&expr, &info, token);
1213 Based on the generic id, figure out which specific procedure is meant and
1214 pick that one. Else return an error, a la _specific. */
1217 ffeintrin_fulfill_generic (ffebld *expr, ffeinfo *info, ffelexToken t)
1222 ffeintrinSpec spec = FFEINTRIN_specNONE;
1223 ffeinfoBasictype bt = FFEINFO_basictypeNONE;
1224 ffeinfoKindtype kt = FFEINFO_kindtypeNONE;
1225 ffetargetCharacterSize sz = FFETARGET_charactersizeNONE;
1227 ffeintrinSpec tspec;
1228 ffeintrinImp nimp = FFEINTRIN_impNONE;
1231 bool highly_specific = FALSE;
1234 op = ffebld_op (*expr);
1235 assert ((op == FFEBLD_opFUNCREF) || (op == FFEBLD_opSUBRREF));
1236 assert (ffebld_op (ffebld_left (*expr)) == FFEBLD_opSYMTER);
1238 gen = ffebld_symter_generic (ffebld_left (*expr));
1239 assert (gen != FFEINTRIN_genNONE);
1241 imp = FFEINTRIN_impNONE;
1244 any = ffeintrin_check_any_ (ffebld_right (*expr));
1247 (((size_t) i) < ARRAY_SIZE (ffeintrin_gens_[gen].specs))
1248 && ((tspec = ffeintrin_gens_[gen].specs[i]) != FFEINTRIN_specNONE)
1252 ffeintrinImp timp = ffeintrin_specs_[tspec].implementation;
1253 ffeinfoBasictype tbt;
1254 ffeinfoKindtype tkt;
1255 ffetargetCharacterSize tsz;
1256 ffeIntrinsicState state
1257 = ffeintrin_state_family (ffeintrin_specs_[tspec].family);
1260 if (state == FFE_intrinsicstateDELETED)
1263 if (timp != FFEINTRIN_impNONE)
1265 if (!(ffeintrin_imps_[timp].control[0] == '-')
1266 != !(ffebld_op (*expr) == FFEBLD_opSUBRREF))
1267 continue; /* Form of reference must match form of specific. */
1270 if (state == FFE_intrinsicstateDISABLED)
1271 terror = FFEBAD_INTRINSIC_DISABLED;
1272 else if (timp == FFEINTRIN_impNONE)
1273 terror = FFEBAD_INTRINSIC_UNIMPL;
1276 terror = ffeintrin_check_ (timp, ffebld_op (*expr),
1277 ffebld_right (*expr),
1278 &tbt, &tkt, &tsz, NULL, t, FALSE);
1279 if (terror == FFEBAD)
1281 if (imp != FFEINTRIN_impNONE)
1283 ffebad_start (FFEBAD_INTRINSIC_AMBIG);
1284 ffebad_here (0, ffelex_token_where_line (t),
1285 ffelex_token_where_column (t));
1286 ffebad_string (ffeintrin_gens_[gen].name);
1287 ffebad_string (ffeintrin_specs_[spec].name);
1288 ffebad_string (ffeintrin_specs_[tspec].name);
1293 if (ffebld_symter_specific (ffebld_left (*expr))
1295 highly_specific = TRUE;
1304 else if (terror != FFEBAD)
1305 { /* This error has precedence over others. */
1306 if ((error == FFEBAD_INTRINSIC_DISABLED)
1307 || (error == FFEBAD_INTRINSIC_UNIMPL))
1312 if (error == FFEBAD)
1316 if (any || (imp == FFEINTRIN_impNONE))
1320 if (error == FFEBAD)
1321 error = FFEBAD_INTRINSIC_REF;
1322 ffebad_start (error);
1323 ffebad_here (0, ffelex_token_where_line (t),
1324 ffelex_token_where_column (t));
1325 ffebad_string (ffeintrin_gens_[gen].name);
1329 *expr = ffebld_new_any ();
1330 *info = ffeinfo_new_any ();
1334 if (!highly_specific && (nimp != FFEINTRIN_impNONE))
1336 fprintf (stderr, "lineno=%ld, gen=%s, imp=%s, timp=%s\n",
1338 ffeintrin_gens_[gen].name,
1339 ffeintrin_imps_[imp].name,
1340 ffeintrin_imps_[nimp].name);
1341 assert ("Ambiguous generic reference" == NULL);
1344 error = ffeintrin_check_ (imp, ffebld_op (*expr),
1345 ffebld_right (*expr),
1346 &bt, &kt, &sz, NULL, t, TRUE);
1347 assert (error == FFEBAD);
1348 *info = ffeinfo_new (bt,
1352 FFEINFO_whereFLEETING,
1354 symter = ffebld_left (*expr);
1355 ffebld_symter_set_specific (symter, spec);
1356 ffebld_symter_set_implementation (symter, imp);
1357 ffebld_set_info (symter,
1361 (bt == FFEINFO_basictypeNONE)
1362 ? FFEINFO_kindSUBROUTINE
1363 : FFEINFO_kindFUNCTION,
1364 FFEINFO_whereINTRINSIC,
1367 if ((ffesymbol_attrs (ffebld_symter (symter)) & FFESYMBOL_attrsTYPE)
1368 && (((bt != ffesymbol_basictype (ffebld_symter (symter)))
1369 || (kt != ffesymbol_kindtype (ffebld_symter (symter)))
1370 || ((sz != FFETARGET_charactersizeNONE)
1371 && (sz != ffesymbol_size (ffebld_symter (symter)))))))
1373 ffebad_start (FFEBAD_INTRINSIC_TYPE);
1374 ffebad_here (0, ffelex_token_where_line (t),
1375 ffelex_token_where_column (t));
1376 ffebad_string (ffeintrin_gens_[gen].name);
1379 if (ffeintrin_imps_[imp].y2kbad)
1381 ffebad_start (FFEBAD_INTRINSIC_Y2KBAD);
1382 ffebad_here (0, ffelex_token_where_line (t),
1383 ffelex_token_where_column (t));
1384 ffebad_string (ffeintrin_gens_[gen].name);
1390 /* Check and fill in info on func/subr ref node.
1392 ffebld expr; // FUNCREF or SUBRREF with no info (caller
1393 // gets it from the modified info structure).
1394 ffeinfo info; // Already filled in, will be overwritten.
1395 bool check_intrin; // May be omitted, else set TRUE if intrinsic needs checking.
1396 ffelexToken token; // Used for error message.
1397 ffeintrin_fulfill_specific (&expr, &info, &check_intrin, token);
1399 Based on the specific id, determine whether the arg list is valid
1400 (number, type, rank, and kind of args) and fill in the info structure
1401 accordingly. Currently don't rewrite the expression, but perhaps
1402 someday do so for constant collapsing, except when an error occurs,
1403 in which case it is overwritten with ANY and info is also overwritten
1407 ffeintrin_fulfill_specific (ffebld *expr, ffeinfo *info,
1408 bool *check_intrin, ffelexToken t)
1415 ffeinfoBasictype bt = FFEINFO_basictypeNONE;
1416 ffeinfoKindtype kt = FFEINFO_kindtypeNONE;
1417 ffetargetCharacterSize sz = FFETARGET_charactersizeNONE;
1418 ffeIntrinsicState state;
1423 op = ffebld_op (*expr);
1424 assert ((op == FFEBLD_opFUNCREF) || (op == FFEBLD_opSUBRREF));
1425 assert (ffebld_op (ffebld_left (*expr)) == FFEBLD_opSYMTER);
1427 gen = ffebld_symter_generic (ffebld_left (*expr));
1428 spec = ffebld_symter_specific (ffebld_left (*expr));
1429 assert (spec != FFEINTRIN_specNONE);
1431 if (gen != FFEINTRIN_genNONE)
1432 name = ffeintrin_gens_[gen].name;
1434 name = ffeintrin_specs_[spec].name;
1436 state = ffeintrin_state_family (ffeintrin_specs_[spec].family);
1438 imp = ffeintrin_specs_[spec].implementation;
1439 if (check_intrin != NULL)
1440 *check_intrin = FALSE;
1442 any = ffeintrin_check_any_ (ffebld_right (*expr));
1444 if (state == FFE_intrinsicstateDISABLED)
1445 error = FFEBAD_INTRINSIC_DISABLED;
1446 else if (imp == FFEINTRIN_impNONE)
1447 error = FFEBAD_INTRINSIC_UNIMPL;
1450 error = ffeintrin_check_ (imp, ffebld_op (*expr),
1451 ffebld_right (*expr),
1452 &bt, &kt, &sz, check_intrin, t, TRUE);
1455 error = FFEBAD; /* Not really needed, but quiet -Wuninitialized. */
1457 if (any || (error != FFEBAD))
1462 ffebad_start (error);
1463 ffebad_here (0, ffelex_token_where_line (t),
1464 ffelex_token_where_column (t));
1465 ffebad_string (name);
1469 *expr = ffebld_new_any ();
1470 *info = ffeinfo_new_any ();
1474 *info = ffeinfo_new (bt,
1478 FFEINFO_whereFLEETING,
1480 symter = ffebld_left (*expr);
1481 ffebld_set_info (symter,
1485 (bt == FFEINFO_basictypeNONE)
1486 ? FFEINFO_kindSUBROUTINE
1487 : FFEINFO_kindFUNCTION,
1488 FFEINFO_whereINTRINSIC,
1491 if ((ffesymbol_attrs (ffebld_symter (symter)) & FFESYMBOL_attrsTYPE)
1492 && (((bt != ffesymbol_basictype (ffebld_symter (symter)))
1493 || (kt != ffesymbol_kindtype (ffebld_symter (symter)))
1494 || (sz != ffesymbol_size (ffebld_symter (symter))))))
1496 ffebad_start (FFEBAD_INTRINSIC_TYPE);
1497 ffebad_here (0, ffelex_token_where_line (t),
1498 ffelex_token_where_column (t));
1499 ffebad_string (name);
1502 if (ffeintrin_imps_[imp].y2kbad)
1504 ffebad_start (FFEBAD_INTRINSIC_Y2KBAD);
1505 ffebad_here (0, ffelex_token_where_line (t),
1506 ffelex_token_where_column (t));
1507 ffebad_string (name);
1513 /* Return run-time index of intrinsic implementation as direct call. */
1516 ffeintrin_gfrt_direct (ffeintrinImp imp)
1518 assert (imp < FFEINTRIN_imp);
1520 return ffeintrin_imps_[imp].gfrt_direct;
1523 /* Return run-time index of intrinsic implementation as actual argument. */
1526 ffeintrin_gfrt_indirect (ffeintrinImp imp)
1528 assert (imp < FFEINTRIN_imp);
1530 if (! ffe_is_f2c ())
1531 return ffeintrin_imps_[imp].gfrt_gnu;
1532 return ffeintrin_imps_[imp].gfrt_f2c;
1544 if (!ffe_is_do_internal_checks ())
1547 assert (FFEINTRIN_gen == ARRAY_SIZE (ffeintrin_gens_));
1548 assert (FFEINTRIN_imp == ARRAY_SIZE (ffeintrin_imps_));
1549 assert (FFEINTRIN_spec == ARRAY_SIZE (ffeintrin_specs_));
1551 for (i = 1; ((size_t) i) < ARRAY_SIZE (ffeintrin_names_); ++i)
1552 { /* Make sure binary-searched list is in alpha
1554 if (strcmp (ffeintrin_names_[i - 1].name_uc,
1555 ffeintrin_names_[i].name_uc) >= 0)
1556 assert ("name list out of order" == NULL);
1559 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffeintrin_names_); ++i)
1561 assert ((ffeintrin_names_[i].generic == FFEINTRIN_genNONE)
1562 || (ffeintrin_names_[i].specific == FFEINTRIN_specNONE));
1564 p1 = ffeintrin_names_[i].name_uc;
1565 p2 = ffeintrin_names_[i].name_lc;
1566 p3 = ffeintrin_names_[i].name_ic;
1567 for (; *p1 != '\0' && *p2 != '\0' && *p3 != '\0'; ++p1, ++p2, ++p3)
1569 if ((ISDIGIT (*p1) || (*p1 == '_')) && (*p1 == *p2) && (*p1 == *p3))
1571 if (! ISUPPER ((unsigned char)*p1) || ! ISLOWER ((unsigned char)*p2)
1572 || (*p1 != TOUPPER (*p2))
1573 || ((*p3 != *p1) && (*p3 != *p2)))
1576 assert ((*p1 == *p2) && (*p1 == *p3) && (*p1 == '\0'));
1579 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffeintrin_imps_); ++i)
1581 const char *c = ffeintrin_imps_[i].control;
1597 fprintf (stderr, "%s: bad return-base-type\n",
1598 ffeintrin_imps_[i].name);
1607 fprintf (stderr, "%s: bad return-kind-type\n",
1608 ffeintrin_imps_[i].name);
1617 fprintf (stderr, "%s: bad return-modifier\n",
1618 ffeintrin_imps_[i].name);
1623 if ((c[colon] != ':') || (c[colon + 2] != ':'))
1625 fprintf (stderr, "%s: bad control\n",
1626 ffeintrin_imps_[i].name);
1629 if ((c[colon + 1] != '-')
1630 && (c[colon + 1] != '*')
1631 && (! ISDIGIT (c[colon + 1])))
1633 fprintf (stderr, "%s: bad COL-spec\n",
1634 ffeintrin_imps_[i].name);
1638 while (c[0] != '\0')
1640 while ((c[0] != '=')
1646 fprintf (stderr, "%s: bad keyword\n",
1647 ffeintrin_imps_[i].name);
1670 fprintf (stderr, "%s: bad arg-base-type\n",
1671 ffeintrin_imps_[i].name);
1679 fprintf (stderr, "%s: bad arg-kind-type\n",
1680 ffeintrin_imps_[i].name);
1685 if ((! ISDIGIT (c[4]))
1687 && (++c, ! ISDIGIT (c[4])
1690 fprintf (stderr, "%s: bad arg-len\n",
1691 ffeintrin_imps_[i].name);
1698 if ((! ISDIGIT (c[4]))
1700 && (++c, ! ISDIGIT (c[4])
1703 fprintf (stderr, "%s: bad arg-rank\n",
1704 ffeintrin_imps_[i].name);
1709 else if ((c[3] == '&')
1724 fprintf (stderr, "%s: bad arg-list\n",
1725 ffeintrin_imps_[i].name);
1732 /* Determine whether intrinsic is okay as an actual argument. */
1735 ffeintrin_is_actualarg (ffeintrinSpec spec)
1737 ffeIntrinsicState state;
1739 if (spec >= FFEINTRIN_spec)
1742 state = ffeintrin_state_family (ffeintrin_specs_[spec].family);
1744 return (!ffe_is_pedantic () || ffeintrin_specs_[spec].is_actualarg)
1746 ? (ffeintrin_imps_[ffeintrin_specs_[spec].implementation].gfrt_f2c
1748 : (ffeintrin_imps_[ffeintrin_specs_[spec].implementation].gfrt_gnu
1750 && ((state == FFE_intrinsicstateENABLED)
1751 || (state == FFE_intrinsicstateHIDDEN));
1754 /* Determine if name is intrinsic, return info.
1756 const char *name; // C-string name of possible intrinsic.
1757 ffelexToken t; // NULL if no diagnostic to be given.
1758 bool explicit; // TRUE if INTRINSIC name.
1759 ffeintrinGen gen; // (TRUE only) Generic id of intrinsic.
1760 ffeintrinSpec spec; // (TRUE only) Specific id of intrinsic.
1761 ffeintrinImp imp; // (TRUE only) Implementation id of intrinsic.
1762 if (ffeintrin_is_intrinsic (name, t, explicit,
1764 // is an intrinsic, use gen, spec, imp, and
1765 // kind accordingly. */
1768 ffeintrin_is_intrinsic (const char *name, ffelexToken t, bool explicit,
1769 ffeintrinGen *xgen, ffeintrinSpec *xspec,
1772 struct _ffeintrin_name_ *intrinsic;
1776 ffeIntrinsicState state;
1777 bool disabled = FALSE;
1778 bool unimpl = FALSE;
1780 intrinsic = bsearch (name, &ffeintrin_names_[0],
1781 ARRAY_SIZE (ffeintrin_names_),
1782 sizeof (struct _ffeintrin_name_),
1783 (void *) ffeintrin_cmp_name_);
1785 if (intrinsic == NULL)
1788 gen = intrinsic->generic;
1789 spec = intrinsic->specific;
1790 imp = ffeintrin_specs_[spec].implementation;
1792 /* Generic is okay only if at least one of its specifics is okay. */
1794 if (gen != FFEINTRIN_genNONE)
1797 ffeintrinSpec tspec;
1800 name = ffeintrin_gens_[gen].name;
1803 (((size_t) i) < ARRAY_SIZE (ffeintrin_gens_[gen].specs))
1805 = ffeintrin_gens_[gen].specs[i]) != FFEINTRIN_specNONE);
1808 state = ffeintrin_state_family (ffeintrin_specs_[tspec].family);
1810 if (state == FFE_intrinsicstateDELETED)
1813 if (state == FFE_intrinsicstateDISABLED)
1819 if (ffeintrin_specs_[tspec].implementation == FFEINTRIN_impNONE)
1825 if ((state == FFE_intrinsicstateENABLED)
1827 && (state == FFE_intrinsicstateHIDDEN)))
1834 gen = FFEINTRIN_genNONE;
1837 /* Specific is okay only if not: unimplemented, disabled, deleted, or
1838 hidden and not explicit. */
1840 if (spec != FFEINTRIN_specNONE)
1842 if (gen != FFEINTRIN_genNONE)
1843 name = ffeintrin_gens_[gen].name;
1845 name = ffeintrin_specs_[spec].name;
1847 if (((state = ffeintrin_state_family (ffeintrin_specs_[spec].family))
1848 == FFE_intrinsicstateDELETED)
1850 && (state == FFE_intrinsicstateHIDDEN)))
1851 spec = FFEINTRIN_specNONE;
1852 else if (state == FFE_intrinsicstateDISABLED)
1855 spec = FFEINTRIN_specNONE;
1857 else if (imp == FFEINTRIN_impNONE)
1860 spec = FFEINTRIN_specNONE;
1864 /* If neither is okay, not an intrinsic. */
1866 if ((gen == FFEINTRIN_genNONE) && (spec == FFEINTRIN_specNONE))
1868 /* Here is where we produce a diagnostic about a reference to a
1869 disabled or unimplemented intrinsic, if the diagnostic is desired. */
1871 if ((disabled || unimpl)
1874 ffebad_start (disabled
1875 ? FFEBAD_INTRINSIC_DISABLED
1876 : FFEBAD_INTRINSIC_UNIMPLW);
1877 ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
1878 ffebad_string (name);
1885 /* Determine whether intrinsic is function or subroutine. If no specific
1886 id, scan list of possible specifics for generic to get consensus. If
1887 not unanimous, or clear from the context, return NONE. */
1889 if (spec == FFEINTRIN_specNONE)
1892 ffeintrinSpec tspec;
1894 bool at_least_one_ok = FALSE;
1897 (((size_t) i) < ARRAY_SIZE (ffeintrin_gens_[gen].specs))
1899 = ffeintrin_gens_[gen].specs[i]) != FFEINTRIN_specNONE);
1902 if (((state = ffeintrin_state_family (ffeintrin_specs_[tspec].family))
1903 == FFE_intrinsicstateDELETED)
1904 || (state == FFE_intrinsicstateDISABLED))
1907 if ((timp = ffeintrin_specs_[tspec].implementation)
1908 == FFEINTRIN_impNONE)
1911 at_least_one_ok = TRUE;
1915 if (!at_least_one_ok)
1917 *xgen = FFEINTRIN_genNONE;
1918 *xspec = FFEINTRIN_specNONE;
1919 *ximp = FFEINTRIN_impNONE;
1930 /* Return TRUE if intrinsic is standard F77 (or, if -ff90, F90). */
1933 ffeintrin_is_standard (ffeintrinGen gen, ffeintrinSpec spec)
1935 if (spec == FFEINTRIN_specNONE)
1937 if (gen == FFEINTRIN_genNONE)
1940 spec = ffeintrin_gens_[gen].specs[0];
1941 if (spec == FFEINTRIN_specNONE)
1945 if ((ffeintrin_specs_[spec].family == FFEINTRIN_familyF77)
1947 && ((ffeintrin_specs_[spec].family == FFEINTRIN_familyF90)
1948 || (ffeintrin_specs_[spec].family == FFEINTRIN_familyMIL)
1949 || (ffeintrin_specs_[spec].family == FFEINTRIN_familyASC))))
1954 /* Return kind type of intrinsic implementation. See ffeintrin_basictype,
1958 ffeintrin_kindtype (ffeintrinSpec spec)
1963 assert (spec < FFEINTRIN_spec);
1964 imp = ffeintrin_specs_[spec].implementation;
1965 assert (imp < FFEINTRIN_imp);
1968 gfrt = ffeintrin_imps_[imp].gfrt_f2c;
1970 gfrt = ffeintrin_imps_[imp].gfrt_gnu;
1972 assert (gfrt != FFECOM_gfrt);
1974 return ffecom_gfrt_kindtype (gfrt);
1977 /* Return name of generic intrinsic. */
1980 ffeintrin_name_generic (ffeintrinGen gen)
1982 assert (gen < FFEINTRIN_gen);
1983 return ffeintrin_gens_[gen].name;
1986 /* Return name of intrinsic implementation. */
1989 ffeintrin_name_implementation (ffeintrinImp imp)
1991 assert (imp < FFEINTRIN_imp);
1992 return ffeintrin_imps_[imp].name;
1995 /* Return external/internal name of specific intrinsic. */
1998 ffeintrin_name_specific (ffeintrinSpec spec)
2000 assert (spec < FFEINTRIN_spec);
2001 return ffeintrin_specs_[spec].name;
2004 /* Return state of family. */
2007 ffeintrin_state_family (ffeintrinFamily family)
2009 ffeIntrinsicState state;
2013 case FFEINTRIN_familyNONE:
2014 return FFE_intrinsicstateDELETED;
2016 case FFEINTRIN_familyF77:
2017 return FFE_intrinsicstateENABLED;
2019 case FFEINTRIN_familyASC:
2020 state = ffe_intrinsic_state_f2c ();
2021 state = ffe_state_max (state, ffe_intrinsic_state_f90 ());
2024 case FFEINTRIN_familyMIL:
2025 state = ffe_intrinsic_state_vxt ();
2026 state = ffe_state_max (state, ffe_intrinsic_state_f90 ());
2027 state = ffe_state_max (state, ffe_intrinsic_state_mil ());
2030 case FFEINTRIN_familyGNU:
2031 state = ffe_intrinsic_state_gnu ();
2034 case FFEINTRIN_familyF90:
2035 state = ffe_intrinsic_state_f90 ();
2038 case FFEINTRIN_familyVXT:
2039 state = ffe_intrinsic_state_vxt ();
2042 case FFEINTRIN_familyFVZ:
2043 state = ffe_intrinsic_state_f2c ();
2044 state = ffe_state_max (state, ffe_intrinsic_state_vxt ());
2047 case FFEINTRIN_familyF2C:
2048 state = ffe_intrinsic_state_f2c ();
2051 case FFEINTRIN_familyF2U:
2052 state = ffe_intrinsic_state_unix ();
2055 case FFEINTRIN_familyBADU77:
2056 state = ffe_intrinsic_state_badu77 ();
2060 assert ("bad family" == NULL);
2061 return FFE_intrinsicstateDELETED;