@@ -793,16 +793,11 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
793
793
DefaultingKIND},
794
794
KINDInt},
795
795
{" __builtin_ieee_is_nan" , {{" a" , AnyFloating}}, DefaultLogical},
796
- {" __builtin_ieee_is_normal" , {{" a" , AnyFloating}}, DefaultLogical},
797
796
{" __builtin_ieee_is_negative" , {{" a" , AnyFloating}}, DefaultLogical},
797
+ {" __builtin_ieee_is_normal" , {{" a" , AnyFloating}}, DefaultLogical},
798
798
{" __builtin_ieee_next_after" , {{" x" , SameReal}, {" y" , AnyReal}}, SameReal},
799
799
{" __builtin_ieee_next_down" , {{" x" , SameReal}}, SameReal},
800
800
{" __builtin_ieee_next_up" , {{" x" , SameReal}}, SameReal},
801
- {" __builtin_ieee_selected_real_kind" , // alias for selected_real_kind
802
- {{" p" , AnyInt, Rank::scalar},
803
- {" r" , AnyInt, Rank::scalar, Optionality::optional},
804
- {" radix" , AnyInt, Rank::scalar, Optionality::optional}},
805
- DefaultInt, Rank::scalar, IntrinsicClass::transformationalFunction},
806
801
{" __builtin_ieee_support_datatype" ,
807
802
{{" x" , AnyReal, Rank::elemental, Optionality::optional}},
808
803
DefaultLogical},
@@ -839,7 +834,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
839
834
// LCOBOUND, UCOBOUND, FAILED_IMAGES, IMAGE_INDEX,
840
835
// STOPPED_IMAGES, COSHAPE
841
836
// TODO: Non-standard intrinsic functions
842
- // AND, OR, XOR, LSHIFT, RSHIFT, SHIFT, ZEXT, IZEXT,
837
+ // LSHIFT, RSHIFT, SHIFT, ZEXT, IZEXT,
843
838
// COMPL, EQV, NEQV, INT8, JINT, JNINT, KNINT,
844
839
// QCMPLX, QEXT, QFLOAT, QREAL, DNUM,
845
840
// INUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN,
@@ -851,6 +846,15 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
851
846
// LOC, probably others
852
847
// TODO: Optionally warn on operand promotion extension
853
848
849
+ // Aliases for a few generic intrinsic functions for legacy
850
+ // compatibility and builtins.
851
+ static const std::pair<const char *, const char *> genericAlias[]{
852
+ {" and" , " iand" },
853
+ {" or" , " ior" },
854
+ {" xor" , " ieor" },
855
+ {" __builtin_ieee_selected_real_kind" , " selected_real_kind" },
856
+ };
857
+
854
858
// The following table contains the intrinsic functions listed in
855
859
// Tables 16.2 and 16.3 in Fortran 2018. The "unrestricted" functions
856
860
// in Table 16.2 can be used as actual arguments, PROCEDURE() interfaces,
@@ -1897,6 +1901,10 @@ class IntrinsicProcTable::Implementation {
1897
1901
for (const IntrinsicInterface &f : genericIntrinsicFunction) {
1898
1902
genericFuncs_.insert (std::make_pair (std::string{f.name }, &f));
1899
1903
}
1904
+ for (const std::pair<const char *, const char *> &a : genericAlias) {
1905
+ aliases_.insert (
1906
+ std::make_pair (std::string{a.first }, std::string{a.second }));
1907
+ }
1900
1908
for (const SpecificIntrinsicInterface &f : specificIntrinsicFunction) {
1901
1909
specificFuncs_.insert (std::make_pair (std::string{f.name }, &f));
1902
1910
}
@@ -1929,16 +1937,22 @@ class IntrinsicProcTable::Implementation {
1929
1937
SpecificCall HandleNull (ActualArguments &, FoldingContext &) const ;
1930
1938
std::optional<SpecificCall> HandleC_F_Pointer (
1931
1939
ActualArguments &, FoldingContext &) const ;
1940
+ const std::string &ResolveAlias (const std::string &name) const {
1941
+ auto iter{aliases_.find (name)};
1942
+ return iter == aliases_.end () ? name : iter->second ;
1943
+ }
1932
1944
1933
1945
common::IntrinsicTypeDefaultKinds defaults_;
1934
1946
std::multimap<std::string, const IntrinsicInterface *> genericFuncs_;
1935
1947
std::multimap<std::string, const SpecificIntrinsicInterface *> specificFuncs_;
1936
1948
std::multimap<std::string, const IntrinsicInterface *> subroutines_;
1937
1949
const semantics::Scope *builtinsScope_{nullptr };
1950
+ std::map<std::string, std::string> aliases_;
1938
1951
};
1939
1952
1940
1953
bool IntrinsicProcTable::Implementation::IsIntrinsicFunction (
1941
- const std::string &name) const {
1954
+ const std::string &name0) const {
1955
+ const std::string &name{ResolveAlias (name0)};
1942
1956
auto specificRange{specificFuncs_.equal_range (name)};
1943
1957
if (specificRange.first != specificRange.second ) {
1944
1958
return true ;
@@ -2427,9 +2441,11 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
2427
2441
return std::nullopt;
2428
2442
}};
2429
2443
2430
- // Probe the generic intrinsic function table first.
2444
+ // Probe the generic intrinsic function table first; allow for
2445
+ // the use of a legacy alias.
2431
2446
parser::Messages genericBuffer;
2432
- auto genericRange{genericFuncs_.equal_range (call.name )};
2447
+ const std::string &name{ResolveAlias (call.name )};
2448
+ auto genericRange{genericFuncs_.equal_range (name)};
2433
2449
for (auto iter{genericRange.first }; iter != genericRange.second ; ++iter) {
2434
2450
if (auto specificCall{
2435
2451
matchOrBufferMessages (*iter->second , genericBuffer)}) {
0 commit comments