1 /* intrin.c -- Recognize references to intrinsics
2 Copyright (C) 1995, 1996, 1997, 1998, 2002,
3 2003 Free Software Foundation, Inc.
4 Contributed by James Craig Burley.
6 This file is part of GNU Fortran.
8 GNU Fortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU Fortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Fortran; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
34 struct _ffeintrin_name_
36 const char *const name_uc
;
37 const char *const name_lc
;
38 const char *const name_ic
;
39 const ffeintrinGen generic
;
40 const ffeintrinSpec specific
;
43 struct _ffeintrin_gen_
45 const char *const name
; /* Name as seen in program. */
46 const ffeintrinSpec specs
[2];
49 struct _ffeintrin_spec_
51 const char *const name
; /* Uppercase name as seen in source code,
52 lowercase if no source name, "none" if no
53 name at all (NONE case). */
54 const bool is_actualarg
; /* Ok to pass as actual arg if -pedantic. */
55 const ffeintrinFamily family
;
56 const ffeintrinImp implementation
;
59 struct _ffeintrin_imp_
61 const char *const name
; /* Name of implementation. */
62 const ffecomGfrt gfrt_direct
;/* library routine, direct-callable form. */
63 const ffecomGfrt gfrt_f2c
; /* library routine, f2c-callable form. */
64 const ffecomGfrt gfrt_gnu
; /* library routine, gnu-callable form. */
65 const char *const control
;
69 static ffebad
ffeintrin_check_ (ffeintrinImp imp
, ffebldOp op
,
70 ffebld args
, ffeinfoBasictype
*xbt
,
72 ffetargetCharacterSize
*xsz
,
76 static bool ffeintrin_check_any_ (ffebld arglist
);
77 static int ffeintrin_cmp_name_ (const void *name
, const void *intrinsic
);
79 static const struct _ffeintrin_name_ ffeintrin_names_
[]
82 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) \
83 { UPPER, LOWER, MIXED, FFEINTRIN_ ## GEN, FFEINTRIN_ ## SPEC },
84 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
85 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
86 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
87 #define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
96 static const struct _ffeintrin_gen_ ffeintrin_gens_
[]
99 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
100 #define DEFGEN(CODE,NAME,SPEC1,SPEC2) \
101 { NAME, { SPEC1, SPEC2, }, },
102 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
103 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
104 #define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
105 #include "intrin.def"
113 static const struct _ffeintrin_imp_ ffeintrin_imps_
[]
116 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
117 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
118 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
119 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \
120 { NAME, FFECOM_gfrt ## GFRTDIRECT, FFECOM_gfrt ## GFRTF2C, \
121 FFECOM_gfrt ## GFRTGNU, CONTROL, FALSE },
122 #define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD) \
123 { NAME, FFECOM_gfrt ## GFRTDIRECT, FFECOM_gfrt ## GFRTF2C, \
124 FFECOM_gfrt ## GFRTGNU, CONTROL, Y2KBAD },
125 #include "intrin.def"
133 static const struct _ffeintrin_spec_ ffeintrin_specs_
[]
136 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
137 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
138 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) \
139 { NAME, CALLABLE, FAMILY, IMP, },
140 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
141 #define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
142 #include "intrin.def"
151 ffeintrin_check_ (ffeintrinImp imp
, ffebldOp op
,
152 ffebld args
, ffeinfoBasictype
*xbt
,
153 ffeinfoKindtype
*xkt
,
154 ffetargetCharacterSize
*xsz
,
159 const char *c
= ffeintrin_imps_
[imp
].control
;
160 bool subr
= (c
[0] == '-');
165 ffetargetCharacterSize sz
= FFETARGET_charactersizeNONE
;
166 ffeinfoKindtype firstarg_kt
;
168 ffeinfoBasictype col_bt
= FFEINFO_basictypeNONE
;
169 ffeinfoKindtype col_kt
= FFEINFO_kindtypeNONE
;
170 int colon
= (c
[2] == ':') ? 2 : 3;
173 /* Check procedure type (function vs. subroutine) against
176 if (op
== FFEBLD_opSUBRREF
)
179 return FFEBAD_INTRINSIC_IS_FUNC
;
181 else if (op
== FFEBLD_opFUNCREF
)
184 return FFEBAD_INTRINSIC_IS_SUBR
;
187 return FFEBAD_INTRINSIC_REF
;
189 /* Check the arglist for validity. */
192 && (ffebld_head (args
) != NULL
))
193 firstarg_kt
= ffeinfo_kindtype (ffebld_info (ffebld_head (args
)));
195 firstarg_kt
= FFEINFO_kindtype
;
197 for (argc
= &c
[colon
+ 3],
202 char optional
= '\0';
203 char required
= '\0';
209 bool lastarg_complex
= FALSE
;
211 /* We don't do anything with keywords yet. */
214 } while (*(++argc
) != '=');
220 optional
= *(argc
++);
224 required
= *(argc
++);
229 length
= *++argc
- '0';
231 length
= 10 * length
+ (*(argc
++) - '0');
238 elements
= *++argc
- '0';
240 elements
= 10 * elements
+ (*(argc
++) - '0');
243 else if (*argc
== '&')
258 /* Break out of this loop only when current arg spec completely
267 ffeinfoBasictype abt
= FFEINFO_basictypeNONE
;
268 ffeinfoKindtype akt
= FFEINFO_kindtypeNONE
;
271 || (ffebld_head (arg
) == NULL
))
273 if (required
!= '\0')
274 return FFEBAD_INTRINSIC_TOOFEW
;
275 if (optional
== '\0')
276 return FFEBAD_INTRINSIC_TOOFEW
;
278 arg
= ffebld_trail (arg
);
279 break; /* Try next argspec. */
282 a
= ffebld_head (arg
);
284 anynum
= (ffeinfo_basictype (i
) == FFEINFO_basictypeHOLLERITH
)
285 || (ffeinfo_basictype (i
) == FFEINFO_basictypeTYPELESS
);
287 /* See how well the arg matches up to the spec. */
292 okay
= (ffeinfo_basictype (i
) == FFEINFO_basictypeCHARACTER
)
294 || (ffeinfo_size (i
) == (ffetargetCharacterSize
) length
));
299 || (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
);
300 abt
= FFEINFO_basictypeCOMPLEX
;
305 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
);
306 abt
= FFEINFO_basictypeINTEGER
;
311 || (ffeinfo_basictype (i
) == FFEINFO_basictypeLOGICAL
);
312 abt
= FFEINFO_basictypeLOGICAL
;
317 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
318 abt
= FFEINFO_basictypeREAL
;
323 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
324 || (ffeinfo_basictype (i
) == FFEINFO_basictypeLOGICAL
);
329 || (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
)
330 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
335 || (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
)
336 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
337 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
342 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
343 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
347 okay
= ((ffebld_op (a
) == FFEBLD_opLABTER
)
348 || (ffebld_op (a
) == FFEBLD_opLABTOK
));
354 okay
= (((((ffeinfo_basictype (i
) == FFEINFO_basictypeNONE
)
355 && (ffeinfo_kindtype (i
) == FFEINFO_kindtypeNONE
)
356 && (ffeinfo_kind (i
) == FFEINFO_kindSUBROUTINE
))
357 || ((ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
358 && (ffeinfo_kindtype (i
) == FFEINFO_kindtypeINTEGERDEFAULT
)
359 && (ffeinfo_kind (i
) == FFEINFO_kindFUNCTION
))
360 || (ffeinfo_kind (i
) == FFEINFO_kindNONE
))
361 && ((ffeinfo_where (i
) == FFEINFO_whereDUMMY
)
362 || (ffeinfo_where (i
) == FFEINFO_whereGLOBAL
)))
363 || ((ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
364 && (ffeinfo_kind (i
) == FFEINFO_kindENTITY
)));
377 case '1': case '2': case '3': case '4': case '5':
378 case '6': case '7': case '8': case '9':
380 if ((ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
381 || (ffeinfo_basictype (i
) == FFEINFO_basictypeLOGICAL
))
384 { /* Translate to internal kinds for now! */
405 akt
= ffecom_pointer_kind ();
409 okay
&= anynum
|| (ffeinfo_kindtype (i
) == akt
);
413 okay
&= anynum
|| (ffeinfo_kindtype (i
) == firstarg_kt
);
414 akt
= (firstarg_kt
== FFEINFO_kindtype
) ? FFEINFO_kindtypeNONE
419 /* Accept integers and logicals not wider than the default integer/logical. */
420 if (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
422 okay
&= anynum
|| (ffeinfo_kindtype (i
) == FFEINFO_kindtypeINTEGER1
423 || ffeinfo_kindtype (i
) == FFEINFO_kindtypeINTEGER2
424 || ffeinfo_kindtype (i
) == FFEINFO_kindtypeINTEGER3
);
425 akt
= FFEINFO_kindtypeINTEGER1
; /* The default. */
427 else if (ffeinfo_basictype (i
) == FFEINFO_basictypeLOGICAL
)
429 okay
&= anynum
|| (ffeinfo_kindtype (i
) == FFEINFO_kindtypeLOGICAL1
430 || ffeinfo_kindtype (i
) == FFEINFO_kindtypeLOGICAL2
431 || ffeinfo_kindtype (i
) == FFEINFO_kindtypeLOGICAL3
);
432 akt
= FFEINFO_kindtypeLOGICAL1
; /* The default. */
449 if (ffeinfo_rank (i
) != 0)
454 if ((ffeinfo_rank (i
) != 1)
455 || (ffebld_op (a
) != FFEBLD_opSYMTER
)
456 || ((b
= ffesymbol_arraysize (ffebld_symter (a
))) == NULL
)
457 || (ffebld_op (b
) != FFEBLD_opCONTER
)
458 || (ffeinfo_basictype (ffebld_info (b
)) != FFEINFO_basictypeINTEGER
)
459 || (ffeinfo_kindtype (ffebld_info (b
)) != FFEINFO_kindtypeINTEGERDEFAULT
)
460 || (ffebld_constant_integer1 (ffebld_conter (b
)) != elements
))
468 if ((ffeinfo_kind (i
) != FFEINFO_kindENTITY
)
469 || ((ffebld_op (a
) != FFEBLD_opSYMTER
)
470 && (ffebld_op (a
) != FFEBLD_opSUBSTR
)
471 && (ffebld_op (a
) != FFEBLD_opARRAYREF
)))
477 if ((ffeinfo_kind (i
) != FFEINFO_kindENTITY
)
478 || ((ffebld_op (a
) != FFEBLD_opSYMTER
)
479 && (ffebld_op (a
) != FFEBLD_opARRAYREF
)
480 && (ffebld_op (a
) != FFEBLD_opSUBSTR
)))
489 if (ffeinfo_kind (i
) != FFEINFO_kindENTITY
)
494 if ((optional
== '!')
500 /* If it wasn't optional, it's an error,
501 else maybe it could match a later argspec. */
502 if (optional
== '\0')
503 return FFEBAD_INTRINSIC_REF
;
504 break; /* Try next argspec. */
508 = (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
);
512 /* If we know dummy arg type, convert to that now. */
514 if ((abt
!= FFEINFO_basictypeNONE
)
515 && (akt
!= FFEINFO_kindtypeNONE
)
518 /* We have a known type, convert hollerith/typeless
521 a
= ffeexpr_convert (a
, t
, NULL
,
523 FFETARGET_charactersizeNONE
,
525 ffebld_set_head (arg
, a
);
529 arg
= ffebld_trail (arg
); /* Arg accepted, now move on. */
532 continue; /* Go ahead and try another arg. */
533 if (required
== '\0')
535 if ((required
== 'n')
536 || (required
== '+'))
541 else if (required
== 'p')
547 return FFEBAD_INTRINSIC_TOOMANY
;
549 /* Set up the initial type for the return value of the function. */
555 bt
= FFEINFO_basictypeCHARACTER
;
556 sz
= (c
[2] == '*') ? FFETARGET_charactersizeNONE
: 1;
560 bt
= FFEINFO_basictypeCOMPLEX
;
564 bt
= FFEINFO_basictypeINTEGER
;
568 bt
= FFEINFO_basictypeLOGICAL
;
572 bt
= FFEINFO_basictypeREAL
;
583 bt
= FFEINFO_basictypeNONE
;
589 case '1': case '2': case '3': case '4': case '5':
590 case '6': case '7': case '8': case '9':
592 if ((bt
== FFEINFO_basictypeINTEGER
)
593 || (bt
== FFEINFO_basictypeLOGICAL
))
596 { /* Translate to internal kinds for now! */
617 kt
= ffecom_pointer_kind ();
634 kt
= FFEINFO_kindtypeNONE
;
638 /* Determine collective type of COL, if there is one. */
640 if (need_col
|| c
[colon
+ 1] != '-')
643 bool have_anynum
= FALSE
;
646 for (arg
= args
, arg_count
=0;
648 arg
= ffebld_trail (arg
), arg_count
++ )
650 ffebld a
= ffebld_head (arg
);
658 if ( c
[colon
+1] != '*' && (c
[colon
+1]-'0') != arg_count
)
661 anynum
= (ffeinfo_basictype (i
) == FFEINFO_basictypeHOLLERITH
)
662 || (ffeinfo_basictype (i
) == FFEINFO_basictypeTYPELESS
);
669 if ((col_bt
== FFEINFO_basictypeNONE
)
670 && (col_kt
== FFEINFO_kindtypeNONE
))
672 col_bt
= ffeinfo_basictype (i
);
673 col_kt
= ffeinfo_kindtype (i
);
677 ffeexpr_type_combine (&col_bt
, &col_kt
,
679 ffeinfo_basictype (i
),
680 ffeinfo_kindtype (i
),
682 if ((col_bt
== FFEINFO_basictypeNONE
)
683 || (col_kt
== FFEINFO_kindtypeNONE
))
684 return FFEBAD_INTRINSIC_REF
;
689 && ((col_bt
== FFEINFO_basictypeNONE
)
690 || (col_kt
== FFEINFO_kindtypeNONE
)))
692 /* No type, but have hollerith/typeless. Use type of return
693 value to determine type of COL. */
698 return FFEBAD_INTRINSIC_REF
;
703 if ((col_bt
!= FFEINFO_basictypeNONE
)
704 && (col_bt
!= FFEINFO_basictypeINTEGER
))
705 return FFEBAD_INTRINSIC_REF
;
711 col_bt
= FFEINFO_basictypeINTEGER
;
712 col_kt
= FFEINFO_kindtypeINTEGER1
;
716 if ((col_bt
!= FFEINFO_basictypeNONE
)
717 && (col_bt
!= FFEINFO_basictypeCOMPLEX
))
718 return FFEBAD_INTRINSIC_REF
;
719 col_bt
= FFEINFO_basictypeCOMPLEX
;
720 col_kt
= FFEINFO_kindtypeREAL1
;
724 if ((col_bt
!= FFEINFO_basictypeNONE
)
725 && (col_bt
!= FFEINFO_basictypeREAL
))
726 return FFEBAD_INTRINSIC_REF
;
729 col_bt
= FFEINFO_basictypeREAL
;
730 col_kt
= FFEINFO_kindtypeREAL1
;
738 okay
= (col_bt
== FFEINFO_basictypeINTEGER
)
739 || (col_bt
== FFEINFO_basictypeLOGICAL
);
745 okay
= (col_bt
== FFEINFO_basictypeCOMPLEX
)
746 || (col_bt
== FFEINFO_basictypeREAL
);
752 okay
= (col_bt
== FFEINFO_basictypeCOMPLEX
)
753 || (col_bt
== FFEINFO_basictypeINTEGER
)
754 || (col_bt
== FFEINFO_basictypeREAL
);
760 okay
= (col_bt
== FFEINFO_basictypeINTEGER
)
761 || (col_bt
== FFEINFO_basictypeREAL
)
762 || (col_bt
== FFEINFO_basictypeCOMPLEX
);
764 bt
= ((col_bt
!= FFEINFO_basictypeCOMPLEX
) ? col_bt
765 : FFEINFO_basictypeREAL
);
777 if (col_bt
== FFEINFO_basictypeCOMPLEX
)
779 if (col_kt
!= FFEINFO_kindtypeREALDEFAULT
)
780 *check_intrin
= TRUE
;
788 return FFEBAD_INTRINSIC_REF
;
791 /* Now, convert args in the arglist to the final type of the COL. */
793 for (argno
= 0, argc
= &c
[colon
+ 3],
798 char optional
= '\0';
799 char required
= '\0';
805 bool lastarg_complex
= FALSE
;
807 /* We don't do anything with keywords yet. */
810 } while (*(++argc
) != '=');
816 optional
= *(argc
++);
820 required
= *(argc
++);
825 length
= *++argc
- '0';
827 length
= 10 * length
+ (*(argc
++) - '0');
834 elements
= *++argc
- '0';
836 elements
= 10 * elements
+ (*(argc
++) - '0');
839 else if (*argc
== '&')
854 /* Break out of this loop only when current arg spec completely
863 ffeinfoBasictype abt
= FFEINFO_basictypeNONE
;
864 ffeinfoKindtype akt
= FFEINFO_kindtypeNONE
;
867 || (ffebld_head (arg
) == NULL
))
870 arg
= ffebld_trail (arg
);
871 break; /* Try next argspec. */
874 a
= ffebld_head (arg
);
876 anynum
= (ffeinfo_basictype (i
) == FFEINFO_basictypeHOLLERITH
)
877 || (ffeinfo_basictype (i
) == FFEINFO_basictypeTYPELESS
);
879 /* Determine what the default type for anynum would be. */
883 switch (c
[colon
+ 1])
887 case '0': case '1': case '2': case '3': case '4':
888 case '5': case '6': case '7': case '8': case '9':
889 if (argno
!= (c
[colon
+ 1] - '0'))
898 /* Again, match arg up to the spec. We go through all of
899 this again to properly follow the contour of optional
900 arguments. Probably this level of flexibility is not
901 needed, perhaps it's even downright naughty. */
906 okay
= (ffeinfo_basictype (i
) == FFEINFO_basictypeCHARACTER
)
908 || (ffeinfo_size (i
) == (ffetargetCharacterSize
) length
));
913 || (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
);
914 abt
= FFEINFO_basictypeCOMPLEX
;
919 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
);
920 abt
= FFEINFO_basictypeINTEGER
;
925 || (ffeinfo_basictype (i
) == FFEINFO_basictypeLOGICAL
);
926 abt
= FFEINFO_basictypeLOGICAL
;
931 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
932 abt
= FFEINFO_basictypeREAL
;
937 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
938 || (ffeinfo_basictype (i
) == FFEINFO_basictypeLOGICAL
);
943 || (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
)
944 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
949 || (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
)
950 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
951 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
956 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
957 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
961 okay
= ((ffebld_op (a
) == FFEBLD_opLABTER
)
962 || (ffebld_op (a
) == FFEBLD_opLABTOK
));
968 okay
= (((((ffeinfo_basictype (i
) == FFEINFO_basictypeNONE
)
969 && (ffeinfo_kindtype (i
) == FFEINFO_kindtypeNONE
)
970 && (ffeinfo_kind (i
) == FFEINFO_kindSUBROUTINE
))
971 || ((ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
972 && (ffeinfo_kindtype (i
) == FFEINFO_kindtypeINTEGERDEFAULT
)
973 && (ffeinfo_kind (i
) == FFEINFO_kindFUNCTION
))
974 || (ffeinfo_kind (i
) == FFEINFO_kindNONE
))
975 && ((ffeinfo_where (i
) == FFEINFO_whereDUMMY
)
976 || (ffeinfo_where (i
) == FFEINFO_whereGLOBAL
)))
977 || ((ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
978 && (ffeinfo_kind (i
) == FFEINFO_kindENTITY
)));
991 case '1': case '2': case '3': case '4': case '5':
992 case '6': case '7': case '8': case '9':
994 if ((ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
995 || (ffeinfo_basictype (i
) == FFEINFO_basictypeLOGICAL
))
998 { /* Translate to internal kinds for now! */
1019 akt
= ffecom_pointer_kind ();
1023 okay
&= anynum
|| (ffeinfo_kindtype (i
) == akt
);
1027 okay
&= anynum
|| (ffeinfo_kindtype (i
) == firstarg_kt
);
1028 akt
= (firstarg_kt
== FFEINFO_kindtype
) ? FFEINFO_kindtypeNONE
1045 if (ffeinfo_rank (i
) != 0)
1050 if ((ffeinfo_rank (i
) != 1)
1051 || (ffebld_op (a
) != FFEBLD_opSYMTER
)
1052 || ((b
= ffesymbol_arraysize (ffebld_symter (a
))) == NULL
)
1053 || (ffebld_op (b
) != FFEBLD_opCONTER
)
1054 || (ffeinfo_basictype (ffebld_info (b
)) != FFEINFO_basictypeINTEGER
)
1055 || (ffeinfo_kindtype (ffebld_info (b
)) != FFEINFO_kindtypeINTEGERDEFAULT
)
1056 || (ffebld_constant_integer1 (ffebld_conter (b
)) != elements
))
1064 if ((ffeinfo_kind (i
) != FFEINFO_kindENTITY
)
1065 || ((ffebld_op (a
) != FFEBLD_opSYMTER
)
1066 && (ffebld_op (a
) != FFEBLD_opSUBSTR
)
1067 && (ffebld_op (a
) != FFEBLD_opARRAYREF
)))
1073 if ((ffeinfo_kind (i
) != FFEINFO_kindENTITY
)
1074 || ((ffebld_op (a
) != FFEBLD_opSYMTER
)
1075 && (ffebld_op (a
) != FFEBLD_opARRAYREF
)
1076 && (ffebld_op (a
) != FFEBLD_opSUBSTR
)))
1085 if (ffeinfo_kind (i
) != FFEINFO_kindENTITY
)
1090 if ((optional
== '!')
1096 /* If it wasn't optional, it's an error,
1097 else maybe it could match a later argspec. */
1098 if (optional
== '\0')
1099 return FFEBAD_INTRINSIC_REF
;
1100 break; /* Try next argspec. */
1104 = (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
);
1106 if (anynum
&& commit
)
1108 /* If we know dummy arg type, convert to that now. */
1110 if (abt
== FFEINFO_basictypeNONE
)
1111 abt
= FFEINFO_basictypeINTEGER
;
1112 if (akt
== FFEINFO_kindtypeNONE
)
1113 akt
= FFEINFO_kindtypeINTEGER1
;
1115 /* We have a known type, convert hollerith/typeless to it. */
1117 a
= ffeexpr_convert (a
, t
, NULL
,
1119 FFETARGET_charactersizeNONE
,
1120 FFEEXPR_contextLET
);
1121 ffebld_set_head (arg
, a
);
1123 else if ((c
[colon
+ 1] == '*') && commit
)
1125 /* This is where we promote types to the consensus
1126 type for the COL. Maybe this is where -fpedantic
1127 should issue a warning as well. */
1129 a
= ffeexpr_convert (a
, t
, NULL
,
1132 FFEEXPR_contextLET
);
1133 ffebld_set_head (arg
, a
);
1136 arg
= ffebld_trail (arg
); /* Arg accepted, now move on. */
1138 if (optional
== '*')
1139 continue; /* Go ahead and try another arg. */
1140 if (required
== '\0')
1142 if ((required
== 'n')
1143 || (required
== '+'))
1148 else if (required
== 'p')
1160 ffeintrin_check_any_ (ffebld arglist
)
1164 for (; arglist
!= NULL
; arglist
= ffebld_trail (arglist
))
1166 item
= ffebld_head (arglist
);
1168 && (ffebld_op (item
) == FFEBLD_opANY
))
1175 /* Compare a forced-to-uppercase name with a known-upper-case name. */
1178 upcasecmp_ (const char *name
, const char *ucname
)
1180 for ( ; *name
!= 0 && *ucname
!= 0; name
++, ucname
++)
1182 int i
= TOUPPER(*name
) - *ucname
;
1188 return *name
- *ucname
;
1191 /* Compare name to intrinsic's name.
1192 The intrinsics table is sorted on the upper case entries; so first
1193 compare irrespective of case on the `uc' entry. If it matches,
1194 compare according to the setting of intrinsics case comparison mode. */
1197 ffeintrin_cmp_name_ (const void *name
, const void *intrinsic
)
1199 const char *const uc
= ((const struct _ffeintrin_name_
*) intrinsic
)->name_uc
;
1200 const char *const lc
= ((const struct _ffeintrin_name_
*) intrinsic
)->name_lc
;
1201 const char *const ic
= ((const struct _ffeintrin_name_
*) intrinsic
)->name_ic
;
1204 if ((i
= upcasecmp_ (name
, uc
)) == 0)
1206 switch (ffe_case_intrin ())
1209 return strcmp(name
, lc
);
1210 case FFE_caseINITCAP
:
1211 return strcmp(name
, ic
);
1220 /* Return basic type of intrinsic implementation, based on its
1221 run-time implementation *only*. (This is used only when
1222 the type of an intrinsic name is needed without having a
1223 list of arguments, i.e. an interface signature, such as when
1224 passing the intrinsic itself, or really the run-time-library
1225 function, as an argument.)
1227 If there's no eligible intrinsic implementation, there must be
1228 a bug somewhere else; no such reference should have been permitted
1229 to go this far. (Well, this might be wrong.) */
1232 ffeintrin_basictype (ffeintrinSpec spec
)
1237 assert (spec
< FFEINTRIN_spec
);
1238 imp
= ffeintrin_specs_
[spec
].implementation
;
1239 assert (imp
< FFEINTRIN_imp
);
1242 gfrt
= ffeintrin_imps_
[imp
].gfrt_f2c
;
1244 gfrt
= ffeintrin_imps_
[imp
].gfrt_gnu
;
1246 assert (gfrt
!= FFECOM_gfrt
);
1248 return ffecom_gfrt_basictype (gfrt
);
1251 /* Return family to which specific intrinsic belongs. */
1254 ffeintrin_family (ffeintrinSpec spec
)
1256 if (spec
>= FFEINTRIN_spec
)
1258 return ffeintrin_specs_
[spec
].family
;
1261 /* Check and fill in info on func/subr ref node.
1263 ffebld expr; // FUNCREF or SUBRREF with no info (caller
1264 // gets it from the modified info structure).
1265 ffeinfo info; // Already filled in, will be overwritten.
1266 ffelexToken token; // Used for error message.
1267 ffeintrin_fulfill_generic (&expr, &info, token);
1269 Based on the generic id, figure out which specific procedure is meant and
1270 pick that one. Else return an error, a la _specific. */
1273 ffeintrin_fulfill_generic (ffebld
*expr
, ffeinfo
*info
, ffelexToken t
)
1278 ffeintrinSpec spec
= FFEINTRIN_specNONE
;
1279 ffeinfoBasictype bt
= FFEINFO_basictypeNONE
;
1280 ffeinfoKindtype kt
= FFEINFO_kindtypeNONE
;
1281 ffetargetCharacterSize sz
= FFETARGET_charactersizeNONE
;
1283 ffeintrinSpec tspec
;
1284 ffeintrinImp nimp
= FFEINTRIN_impNONE
;
1287 bool highly_specific
= FALSE
;
1290 op
= ffebld_op (*expr
);
1291 assert ((op
== FFEBLD_opFUNCREF
) || (op
== FFEBLD_opSUBRREF
));
1292 assert (ffebld_op (ffebld_left (*expr
)) == FFEBLD_opSYMTER
);
1294 gen
= ffebld_symter_generic (ffebld_left (*expr
));
1295 assert (gen
!= FFEINTRIN_genNONE
);
1297 imp
= FFEINTRIN_impNONE
;
1300 any
= ffeintrin_check_any_ (ffebld_right (*expr
));
1303 (((size_t) i
) < ARRAY_SIZE (ffeintrin_gens_
[gen
].specs
))
1304 && ((tspec
= ffeintrin_gens_
[gen
].specs
[i
]) != FFEINTRIN_specNONE
)
1308 ffeintrinImp timp
= ffeintrin_specs_
[tspec
].implementation
;
1309 ffeinfoBasictype tbt
;
1310 ffeinfoKindtype tkt
;
1311 ffetargetCharacterSize tsz
;
1312 ffeIntrinsicState state
1313 = ffeintrin_state_family (ffeintrin_specs_
[tspec
].family
);
1316 if (state
== FFE_intrinsicstateDELETED
)
1319 if (timp
!= FFEINTRIN_impNONE
)
1321 if (!(ffeintrin_imps_
[timp
].control
[0] == '-')
1322 != !(ffebld_op (*expr
) == FFEBLD_opSUBRREF
))
1323 continue; /* Form of reference must match form of specific. */
1326 if (state
== FFE_intrinsicstateDISABLED
)
1327 terror
= FFEBAD_INTRINSIC_DISABLED
;
1328 else if (timp
== FFEINTRIN_impNONE
)
1329 terror
= FFEBAD_INTRINSIC_UNIMPL
;
1332 terror
= ffeintrin_check_ (timp
, ffebld_op (*expr
),
1333 ffebld_right (*expr
),
1334 &tbt
, &tkt
, &tsz
, NULL
, t
, FALSE
);
1335 if (terror
== FFEBAD
)
1337 if (imp
!= FFEINTRIN_impNONE
)
1339 ffebad_start (FFEBAD_INTRINSIC_AMBIG
);
1340 ffebad_here (0, ffelex_token_where_line (t
),
1341 ffelex_token_where_column (t
));
1342 ffebad_string (ffeintrin_gens_
[gen
].name
);
1343 ffebad_string (ffeintrin_specs_
[spec
].name
);
1344 ffebad_string (ffeintrin_specs_
[tspec
].name
);
1349 if (ffebld_symter_specific (ffebld_left (*expr
))
1351 highly_specific
= TRUE
;
1360 else if (terror
!= FFEBAD
)
1361 { /* This error has precedence over others. */
1362 if ((error
== FFEBAD_INTRINSIC_DISABLED
)
1363 || (error
== FFEBAD_INTRINSIC_UNIMPL
))
1368 if (error
== FFEBAD
)
1372 if (any
|| (imp
== FFEINTRIN_impNONE
))
1376 if (error
== FFEBAD
)
1377 error
= FFEBAD_INTRINSIC_REF
;
1378 ffebad_start (error
);
1379 ffebad_here (0, ffelex_token_where_line (t
),
1380 ffelex_token_where_column (t
));
1381 ffebad_string (ffeintrin_gens_
[gen
].name
);
1385 *expr
= ffebld_new_any ();
1386 *info
= ffeinfo_new_any ();
1390 if (!highly_specific
&& (nimp
!= FFEINTRIN_impNONE
))
1392 fprintf (stderr
, "lineno=%ld, gen=%s, imp=%s, timp=%s\n",
1394 ffeintrin_gens_
[gen
].name
,
1395 ffeintrin_imps_
[imp
].name
,
1396 ffeintrin_imps_
[nimp
].name
);
1397 assert ("Ambiguous generic reference" == NULL
);
1400 error
= ffeintrin_check_ (imp
, ffebld_op (*expr
),
1401 ffebld_right (*expr
),
1402 &bt
, &kt
, &sz
, NULL
, t
, TRUE
);
1403 assert (error
== FFEBAD
);
1404 *info
= ffeinfo_new (bt
,
1408 FFEINFO_whereFLEETING
,
1410 symter
= ffebld_left (*expr
);
1411 ffebld_symter_set_specific (symter
, spec
);
1412 ffebld_symter_set_implementation (symter
, imp
);
1413 ffebld_set_info (symter
,
1417 (bt
== FFEINFO_basictypeNONE
)
1418 ? FFEINFO_kindSUBROUTINE
1419 : FFEINFO_kindFUNCTION
,
1420 FFEINFO_whereINTRINSIC
,
1423 if ((ffesymbol_attrs (ffebld_symter (symter
)) & FFESYMBOL_attrsTYPE
)
1424 && (((bt
!= ffesymbol_basictype (ffebld_symter (symter
)))
1425 || (kt
!= ffesymbol_kindtype (ffebld_symter (symter
)))
1426 || ((sz
!= FFETARGET_charactersizeNONE
)
1427 && (sz
!= ffesymbol_size (ffebld_symter (symter
)))))))
1429 ffebad_start (FFEBAD_INTRINSIC_TYPE
);
1430 ffebad_here (0, ffelex_token_where_line (t
),
1431 ffelex_token_where_column (t
));
1432 ffebad_string (ffeintrin_gens_
[gen
].name
);
1435 if (ffeintrin_imps_
[imp
].y2kbad
)
1437 ffebad_start (FFEBAD_INTRINSIC_Y2KBAD
);
1438 ffebad_here (0, ffelex_token_where_line (t
),
1439 ffelex_token_where_column (t
));
1440 ffebad_string (ffeintrin_gens_
[gen
].name
);
1446 /* Check and fill in info on func/subr ref node.
1448 ffebld expr; // FUNCREF or SUBRREF with no info (caller
1449 // gets it from the modified info structure).
1450 ffeinfo info; // Already filled in, will be overwritten.
1451 bool check_intrin; // May be omitted, else set TRUE if intrinsic needs checking.
1452 ffelexToken token; // Used for error message.
1453 ffeintrin_fulfill_specific (&expr, &info, &check_intrin, token);
1455 Based on the specific id, determine whether the arg list is valid
1456 (number, type, rank, and kind of args) and fill in the info structure
1457 accordingly. Currently don't rewrite the expression, but perhaps
1458 someday do so for constant collapsing, except when an error occurs,
1459 in which case it is overwritten with ANY and info is also overwritten
1463 ffeintrin_fulfill_specific (ffebld
*expr
, ffeinfo
*info
,
1464 bool *check_intrin
, ffelexToken t
)
1471 ffeinfoBasictype bt
= FFEINFO_basictypeNONE
;
1472 ffeinfoKindtype kt
= FFEINFO_kindtypeNONE
;
1473 ffetargetCharacterSize sz
= FFETARGET_charactersizeNONE
;
1474 ffeIntrinsicState state
;
1479 op
= ffebld_op (*expr
);
1480 assert ((op
== FFEBLD_opFUNCREF
) || (op
== FFEBLD_opSUBRREF
));
1481 assert (ffebld_op (ffebld_left (*expr
)) == FFEBLD_opSYMTER
);
1483 gen
= ffebld_symter_generic (ffebld_left (*expr
));
1484 spec
= ffebld_symter_specific (ffebld_left (*expr
));
1485 assert (spec
!= FFEINTRIN_specNONE
);
1487 if (gen
!= FFEINTRIN_genNONE
)
1488 name
= ffeintrin_gens_
[gen
].name
;
1490 name
= ffeintrin_specs_
[spec
].name
;
1492 state
= ffeintrin_state_family (ffeintrin_specs_
[spec
].family
);
1494 imp
= ffeintrin_specs_
[spec
].implementation
;
1495 if (check_intrin
!= NULL
)
1496 *check_intrin
= FALSE
;
1498 any
= ffeintrin_check_any_ (ffebld_right (*expr
));
1500 if (state
== FFE_intrinsicstateDISABLED
)
1501 error
= FFEBAD_INTRINSIC_DISABLED
;
1502 else if (imp
== FFEINTRIN_impNONE
)
1503 error
= FFEBAD_INTRINSIC_UNIMPL
;
1506 error
= ffeintrin_check_ (imp
, ffebld_op (*expr
),
1507 ffebld_right (*expr
),
1508 &bt
, &kt
, &sz
, check_intrin
, t
, TRUE
);
1511 error
= FFEBAD
; /* Not really needed, but quiet -Wuninitialized. */
1513 if (any
|| (error
!= FFEBAD
))
1518 ffebad_start (error
);
1519 ffebad_here (0, ffelex_token_where_line (t
),
1520 ffelex_token_where_column (t
));
1521 ffebad_string (name
);
1525 *expr
= ffebld_new_any ();
1526 *info
= ffeinfo_new_any ();
1530 *info
= ffeinfo_new (bt
,
1534 FFEINFO_whereFLEETING
,
1536 symter
= ffebld_left (*expr
);
1537 ffebld_set_info (symter
,
1541 (bt
== FFEINFO_basictypeNONE
)
1542 ? FFEINFO_kindSUBROUTINE
1543 : FFEINFO_kindFUNCTION
,
1544 FFEINFO_whereINTRINSIC
,
1547 if ((ffesymbol_attrs (ffebld_symter (symter
)) & FFESYMBOL_attrsTYPE
)
1548 && (((bt
!= ffesymbol_basictype (ffebld_symter (symter
)))
1549 || (kt
!= ffesymbol_kindtype (ffebld_symter (symter
)))
1550 || (sz
!= ffesymbol_size (ffebld_symter (symter
))))))
1552 ffebad_start (FFEBAD_INTRINSIC_TYPE
);
1553 ffebad_here (0, ffelex_token_where_line (t
),
1554 ffelex_token_where_column (t
));
1555 ffebad_string (name
);
1558 if (ffeintrin_imps_
[imp
].y2kbad
)
1560 ffebad_start (FFEBAD_INTRINSIC_Y2KBAD
);
1561 ffebad_here (0, ffelex_token_where_line (t
),
1562 ffelex_token_where_column (t
));
1563 ffebad_string (name
);
1569 /* Return run-time index of intrinsic implementation as direct call. */
1572 ffeintrin_gfrt_direct (ffeintrinImp imp
)
1574 assert (imp
< FFEINTRIN_imp
);
1576 return ffeintrin_imps_
[imp
].gfrt_direct
;
1579 /* Return run-time index of intrinsic implementation as actual argument. */
1582 ffeintrin_gfrt_indirect (ffeintrinImp imp
)
1584 assert (imp
< FFEINTRIN_imp
);
1586 if (! ffe_is_f2c ())
1587 return ffeintrin_imps_
[imp
].gfrt_gnu
;
1588 return ffeintrin_imps_
[imp
].gfrt_f2c
;
1600 if (!ffe_is_do_internal_checks ())
1603 assert (FFEINTRIN_gen
== ARRAY_SIZE (ffeintrin_gens_
));
1604 assert (FFEINTRIN_imp
== ARRAY_SIZE (ffeintrin_imps_
));
1605 assert (FFEINTRIN_spec
== ARRAY_SIZE (ffeintrin_specs_
));
1607 for (i
= 1; ((size_t) i
) < ARRAY_SIZE (ffeintrin_names_
); ++i
)
1608 { /* Make sure binary-searched list is in alpha
1610 if (strcmp (ffeintrin_names_
[i
- 1].name_uc
,
1611 ffeintrin_names_
[i
].name_uc
) >= 0)
1612 assert ("name list out of order" == NULL
);
1615 for (i
= 0; ((size_t) i
) < ARRAY_SIZE (ffeintrin_names_
); ++i
)
1617 assert ((ffeintrin_names_
[i
].generic
== FFEINTRIN_genNONE
)
1618 || (ffeintrin_names_
[i
].specific
== FFEINTRIN_specNONE
));
1620 p1
= ffeintrin_names_
[i
].name_uc
;
1621 p2
= ffeintrin_names_
[i
].name_lc
;
1622 p3
= ffeintrin_names_
[i
].name_ic
;
1623 for (; *p1
!= '\0' && *p2
!= '\0' && *p3
!= '\0'; ++p1
, ++p2
, ++p3
)
1625 if ((ISDIGIT (*p1
) || (*p1
== '_')) && (*p1
== *p2
) && (*p1
== *p3
))
1627 if (! ISUPPER ((unsigned char)*p1
) || ! ISLOWER ((unsigned char)*p2
)
1628 || (*p1
!= TOUPPER (*p2
))
1629 || ((*p3
!= *p1
) && (*p3
!= *p2
)))
1632 assert ((*p1
== *p2
) && (*p1
== *p3
) && (*p1
== '\0'));
1635 for (i
= 0; ((size_t) i
) < ARRAY_SIZE (ffeintrin_imps_
); ++i
)
1637 const char *c
= ffeintrin_imps_
[i
].control
;
1653 fprintf (stderr
, "%s: bad return-base-type\n",
1654 ffeintrin_imps_
[i
].name
);
1663 fprintf (stderr
, "%s: bad return-kind-type\n",
1664 ffeintrin_imps_
[i
].name
);
1673 fprintf (stderr
, "%s: bad return-modifier\n",
1674 ffeintrin_imps_
[i
].name
);
1679 if ((c
[colon
] != ':') || (c
[colon
+ 2] != ':'))
1681 fprintf (stderr
, "%s: bad control\n",
1682 ffeintrin_imps_
[i
].name
);
1685 if ((c
[colon
+ 1] != '-')
1686 && (c
[colon
+ 1] != '*')
1687 && (! ISDIGIT (c
[colon
+ 1])))
1689 fprintf (stderr
, "%s: bad COL-spec\n",
1690 ffeintrin_imps_
[i
].name
);
1694 while (c
[0] != '\0')
1696 while ((c
[0] != '=')
1702 fprintf (stderr
, "%s: bad keyword\n",
1703 ffeintrin_imps_
[i
].name
);
1726 fprintf (stderr
, "%s: bad arg-base-type\n",
1727 ffeintrin_imps_
[i
].name
);
1735 fprintf (stderr
, "%s: bad arg-kind-type\n",
1736 ffeintrin_imps_
[i
].name
);
1741 if ((! ISDIGIT (c
[4]))
1743 && (++c
, ! ISDIGIT (c
[4])
1746 fprintf (stderr
, "%s: bad arg-len\n",
1747 ffeintrin_imps_
[i
].name
);
1754 if ((! ISDIGIT (c
[4]))
1756 && (++c
, ! ISDIGIT (c
[4])
1759 fprintf (stderr
, "%s: bad arg-rank\n",
1760 ffeintrin_imps_
[i
].name
);
1765 else if ((c
[3] == '&')
1780 fprintf (stderr
, "%s: bad arg-list\n",
1781 ffeintrin_imps_
[i
].name
);
1788 /* Determine whether intrinsic is okay as an actual argument. */
1791 ffeintrin_is_actualarg (ffeintrinSpec spec
)
1793 ffeIntrinsicState state
;
1795 if (spec
>= FFEINTRIN_spec
)
1798 state
= ffeintrin_state_family (ffeintrin_specs_
[spec
].family
);
1800 return (!ffe_is_pedantic () || ffeintrin_specs_
[spec
].is_actualarg
)
1802 ? (ffeintrin_imps_
[ffeintrin_specs_
[spec
].implementation
].gfrt_f2c
1804 : (ffeintrin_imps_
[ffeintrin_specs_
[spec
].implementation
].gfrt_gnu
1806 && ((state
== FFE_intrinsicstateENABLED
)
1807 || (state
== FFE_intrinsicstateHIDDEN
));
1810 /* Determine if name is intrinsic, return info.
1812 const char *name; // C-string name of possible intrinsic.
1813 ffelexToken t; // NULL if no diagnostic to be given.
1814 bool explicit; // TRUE if INTRINSIC name.
1815 ffeintrinGen gen; // (TRUE only) Generic id of intrinsic.
1816 ffeintrinSpec spec; // (TRUE only) Specific id of intrinsic.
1817 ffeintrinImp imp; // (TRUE only) Implementation id of intrinsic.
1818 if (ffeintrin_is_intrinsic (name, t, explicit,
1820 // is an intrinsic, use gen, spec, imp, and
1821 // kind accordingly. */
1824 ffeintrin_is_intrinsic (const char *name
, ffelexToken t
, bool explicit,
1825 ffeintrinGen
*xgen
, ffeintrinSpec
*xspec
,
1828 struct _ffeintrin_name_
*intrinsic
;
1832 ffeIntrinsicState state
;
1833 bool disabled
= FALSE
;
1834 bool unimpl
= FALSE
;
1836 intrinsic
= bsearch (name
, &ffeintrin_names_
[0],
1837 ARRAY_SIZE (ffeintrin_names_
),
1838 sizeof (struct _ffeintrin_name_
),
1839 (void *) ffeintrin_cmp_name_
);
1841 if (intrinsic
== NULL
)
1844 gen
= intrinsic
->generic
;
1845 spec
= intrinsic
->specific
;
1846 imp
= ffeintrin_specs_
[spec
].implementation
;
1848 /* Generic is okay only if at least one of its specifics is okay. */
1850 if (gen
!= FFEINTRIN_genNONE
)
1853 ffeintrinSpec tspec
;
1856 name
= ffeintrin_gens_
[gen
].name
;
1859 (((size_t) i
) < ARRAY_SIZE (ffeintrin_gens_
[gen
].specs
))
1861 = ffeintrin_gens_
[gen
].specs
[i
]) != FFEINTRIN_specNONE
);
1864 state
= ffeintrin_state_family (ffeintrin_specs_
[tspec
].family
);
1866 if (state
== FFE_intrinsicstateDELETED
)
1869 if (state
== FFE_intrinsicstateDISABLED
)
1875 if (ffeintrin_specs_
[tspec
].implementation
== FFEINTRIN_impNONE
)
1881 if ((state
== FFE_intrinsicstateENABLED
)
1883 && (state
== FFE_intrinsicstateHIDDEN
)))
1890 gen
= FFEINTRIN_genNONE
;
1893 /* Specific is okay only if not: unimplemented, disabled, deleted, or
1894 hidden and not explicit. */
1896 if (spec
!= FFEINTRIN_specNONE
)
1898 if (gen
!= FFEINTRIN_genNONE
)
1899 name
= ffeintrin_gens_
[gen
].name
;
1901 name
= ffeintrin_specs_
[spec
].name
;
1903 if (((state
= ffeintrin_state_family (ffeintrin_specs_
[spec
].family
))
1904 == FFE_intrinsicstateDELETED
)
1906 && (state
== FFE_intrinsicstateHIDDEN
)))
1907 spec
= FFEINTRIN_specNONE
;
1908 else if (state
== FFE_intrinsicstateDISABLED
)
1911 spec
= FFEINTRIN_specNONE
;
1913 else if (imp
== FFEINTRIN_impNONE
)
1916 spec
= FFEINTRIN_specNONE
;
1920 /* If neither is okay, not an intrinsic. */
1922 if ((gen
== FFEINTRIN_genNONE
) && (spec
== FFEINTRIN_specNONE
))
1924 /* Here is where we produce a diagnostic about a reference to a
1925 disabled or unimplemented intrinsic, if the diagnostic is desired. */
1927 if ((disabled
|| unimpl
)
1930 ffebad_start (disabled
1931 ? FFEBAD_INTRINSIC_DISABLED
1932 : FFEBAD_INTRINSIC_UNIMPLW
);
1933 ffebad_here (0, ffelex_token_where_line (t
), ffelex_token_where_column (t
));
1934 ffebad_string (name
);
1941 /* Determine whether intrinsic is function or subroutine. If no specific
1942 id, scan list of possible specifics for generic to get consensus. If
1943 not unanimous, or clear from the context, return NONE. */
1945 if (spec
== FFEINTRIN_specNONE
)
1948 ffeintrinSpec tspec
;
1950 bool at_least_one_ok
= FALSE
;
1953 (((size_t) i
) < ARRAY_SIZE (ffeintrin_gens_
[gen
].specs
))
1955 = ffeintrin_gens_
[gen
].specs
[i
]) != FFEINTRIN_specNONE
);
1958 if (((state
= ffeintrin_state_family (ffeintrin_specs_
[tspec
].family
))
1959 == FFE_intrinsicstateDELETED
)
1960 || (state
== FFE_intrinsicstateDISABLED
))
1963 if ((timp
= ffeintrin_specs_
[tspec
].implementation
)
1964 == FFEINTRIN_impNONE
)
1967 at_least_one_ok
= TRUE
;
1971 if (!at_least_one_ok
)
1973 *xgen
= FFEINTRIN_genNONE
;
1974 *xspec
= FFEINTRIN_specNONE
;
1975 *ximp
= FFEINTRIN_impNONE
;
1986 /* Return TRUE if intrinsic is standard F77 (or, if -ff90, F90). */
1989 ffeintrin_is_standard (ffeintrinGen gen
, ffeintrinSpec spec
)
1991 if (spec
== FFEINTRIN_specNONE
)
1993 if (gen
== FFEINTRIN_genNONE
)
1996 spec
= ffeintrin_gens_
[gen
].specs
[0];
1997 if (spec
== FFEINTRIN_specNONE
)
2001 if ((ffeintrin_specs_
[spec
].family
== FFEINTRIN_familyF77
)
2003 && ((ffeintrin_specs_
[spec
].family
== FFEINTRIN_familyF90
)
2004 || (ffeintrin_specs_
[spec
].family
== FFEINTRIN_familyMIL
)
2005 || (ffeintrin_specs_
[spec
].family
== FFEINTRIN_familyASC
))))
2010 /* Return kind type of intrinsic implementation. See ffeintrin_basictype,
2014 ffeintrin_kindtype (ffeintrinSpec spec
)
2019 assert (spec
< FFEINTRIN_spec
);
2020 imp
= ffeintrin_specs_
[spec
].implementation
;
2021 assert (imp
< FFEINTRIN_imp
);
2024 gfrt
= ffeintrin_imps_
[imp
].gfrt_f2c
;
2026 gfrt
= ffeintrin_imps_
[imp
].gfrt_gnu
;
2028 assert (gfrt
!= FFECOM_gfrt
);
2030 return ffecom_gfrt_kindtype (gfrt
);
2033 /* Return name of generic intrinsic. */
2036 ffeintrin_name_generic (ffeintrinGen gen
)
2038 assert (gen
< FFEINTRIN_gen
);
2039 return ffeintrin_gens_
[gen
].name
;
2042 /* Return name of intrinsic implementation. */
2045 ffeintrin_name_implementation (ffeintrinImp imp
)
2047 assert (imp
< FFEINTRIN_imp
);
2048 return ffeintrin_imps_
[imp
].name
;
2051 /* Return external/internal name of specific intrinsic. */
2054 ffeintrin_name_specific (ffeintrinSpec spec
)
2056 assert (spec
< FFEINTRIN_spec
);
2057 return ffeintrin_specs_
[spec
].name
;
2060 /* Return state of family. */
2063 ffeintrin_state_family (ffeintrinFamily family
)
2065 ffeIntrinsicState state
;
2069 case FFEINTRIN_familyNONE
:
2070 return FFE_intrinsicstateDELETED
;
2072 case FFEINTRIN_familyF77
:
2073 return FFE_intrinsicstateENABLED
;
2075 case FFEINTRIN_familyASC
:
2076 state
= ffe_intrinsic_state_f2c ();
2077 state
= ffe_state_max (state
, ffe_intrinsic_state_f90 ());
2080 case FFEINTRIN_familyMIL
:
2081 state
= ffe_intrinsic_state_vxt ();
2082 state
= ffe_state_max (state
, ffe_intrinsic_state_f90 ());
2083 state
= ffe_state_max (state
, ffe_intrinsic_state_mil ());
2086 case FFEINTRIN_familyGNU
:
2087 state
= ffe_intrinsic_state_gnu ();
2090 case FFEINTRIN_familyF90
:
2091 state
= ffe_intrinsic_state_f90 ();
2094 case FFEINTRIN_familyVXT
:
2095 state
= ffe_intrinsic_state_vxt ();
2098 case FFEINTRIN_familyFVZ
:
2099 state
= ffe_intrinsic_state_f2c ();
2100 state
= ffe_state_max (state
, ffe_intrinsic_state_vxt ());
2103 case FFEINTRIN_familyF2C
:
2104 state
= ffe_intrinsic_state_f2c ();
2107 case FFEINTRIN_familyF2U
:
2108 state
= ffe_intrinsic_state_unix ();
2111 case FFEINTRIN_familyBADU77
:
2112 state
= ffe_intrinsic_state_badu77 ();
2116 assert ("bad family" == NULL
);
2117 return FFE_intrinsicstateDELETED
;