forked from OSchip/llvm-project
[flang] Accept legacy aliases for intrinsic function names
Support the names AND, OR, and XOR for the generic intrinsic functions IAND, IOR, and IEOR respectively. Differential Revision: https://reviews.llvm.org/D122034
This commit is contained in:
parent
251d062e4e
commit
b8f029c3a4
|
@ -223,6 +223,9 @@ end
|
|||
as if they were comment lines, even if not begun with `!`.
|
||||
* Commas are required in FORMAT statements and character variables
|
||||
only when they prevent ambiguity.
|
||||
* Legacy names `AND`, `OR`, and `XOR` are accepted as aliases for
|
||||
the standard intrinsic functions `IAND`, `IOR`, and `IEOR`
|
||||
respectively.
|
||||
|
||||
### Extensions supported when enabled by options
|
||||
|
||||
|
|
|
@ -793,16 +793,11 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
|
|||
DefaultingKIND},
|
||||
KINDInt},
|
||||
{"__builtin_ieee_is_nan", {{"a", AnyFloating}}, DefaultLogical},
|
||||
{"__builtin_ieee_is_normal", {{"a", AnyFloating}}, DefaultLogical},
|
||||
{"__builtin_ieee_is_negative", {{"a", AnyFloating}}, DefaultLogical},
|
||||
{"__builtin_ieee_is_normal", {{"a", AnyFloating}}, DefaultLogical},
|
||||
{"__builtin_ieee_next_after", {{"x", SameReal}, {"y", AnyReal}}, SameReal},
|
||||
{"__builtin_ieee_next_down", {{"x", SameReal}}, SameReal},
|
||||
{"__builtin_ieee_next_up", {{"x", SameReal}}, SameReal},
|
||||
{"__builtin_ieee_selected_real_kind", // alias for selected_real_kind
|
||||
{{"p", AnyInt, Rank::scalar},
|
||||
{"r", AnyInt, Rank::scalar, Optionality::optional},
|
||||
{"radix", AnyInt, Rank::scalar, Optionality::optional}},
|
||||
DefaultInt, Rank::scalar, IntrinsicClass::transformationalFunction},
|
||||
{"__builtin_ieee_support_datatype",
|
||||
{{"x", AnyReal, Rank::elemental, Optionality::optional}},
|
||||
DefaultLogical},
|
||||
|
@ -839,7 +834,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
|
|||
// LCOBOUND, UCOBOUND, FAILED_IMAGES, IMAGE_INDEX,
|
||||
// STOPPED_IMAGES, COSHAPE
|
||||
// TODO: Non-standard intrinsic functions
|
||||
// AND, OR, XOR, LSHIFT, RSHIFT, SHIFT, ZEXT, IZEXT,
|
||||
// LSHIFT, RSHIFT, SHIFT, ZEXT, IZEXT,
|
||||
// COMPL, EQV, NEQV, INT8, JINT, JNINT, KNINT,
|
||||
// QCMPLX, QEXT, QFLOAT, QREAL, DNUM,
|
||||
// INUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN,
|
||||
|
@ -851,6 +846,15 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
|
|||
// LOC, probably others
|
||||
// TODO: Optionally warn on operand promotion extension
|
||||
|
||||
// Aliases for a few generic intrinsic functions for legacy
|
||||
// compatibility and builtins.
|
||||
static const std::pair<const char *, const char *> genericAlias[]{
|
||||
{"and", "iand"},
|
||||
{"or", "ior"},
|
||||
{"xor", "ieor"},
|
||||
{"__builtin_ieee_selected_real_kind", "selected_real_kind"},
|
||||
};
|
||||
|
||||
// The following table contains the intrinsic functions listed in
|
||||
// Tables 16.2 and 16.3 in Fortran 2018. The "unrestricted" functions
|
||||
// in Table 16.2 can be used as actual arguments, PROCEDURE() interfaces,
|
||||
|
@ -1897,6 +1901,10 @@ public:
|
|||
for (const IntrinsicInterface &f : genericIntrinsicFunction) {
|
||||
genericFuncs_.insert(std::make_pair(std::string{f.name}, &f));
|
||||
}
|
||||
for (const std::pair<const char *, const char *> &a : genericAlias) {
|
||||
aliases_.insert(
|
||||
std::make_pair(std::string{a.first}, std::string{a.second}));
|
||||
}
|
||||
for (const SpecificIntrinsicInterface &f : specificIntrinsicFunction) {
|
||||
specificFuncs_.insert(std::make_pair(std::string{f.name}, &f));
|
||||
}
|
||||
|
@ -1929,16 +1937,22 @@ private:
|
|||
SpecificCall HandleNull(ActualArguments &, FoldingContext &) const;
|
||||
std::optional<SpecificCall> HandleC_F_Pointer(
|
||||
ActualArguments &, FoldingContext &) const;
|
||||
const std::string &ResolveAlias(const std::string &name) const {
|
||||
auto iter{aliases_.find(name)};
|
||||
return iter == aliases_.end() ? name : iter->second;
|
||||
}
|
||||
|
||||
common::IntrinsicTypeDefaultKinds defaults_;
|
||||
std::multimap<std::string, const IntrinsicInterface *> genericFuncs_;
|
||||
std::multimap<std::string, const SpecificIntrinsicInterface *> specificFuncs_;
|
||||
std::multimap<std::string, const IntrinsicInterface *> subroutines_;
|
||||
const semantics::Scope *builtinsScope_{nullptr};
|
||||
std::map<std::string, std::string> aliases_;
|
||||
};
|
||||
|
||||
bool IntrinsicProcTable::Implementation::IsIntrinsicFunction(
|
||||
const std::string &name) const {
|
||||
const std::string &name0) const {
|
||||
const std::string &name{ResolveAlias(name0)};
|
||||
auto specificRange{specificFuncs_.equal_range(name)};
|
||||
if (specificRange.first != specificRange.second) {
|
||||
return true;
|
||||
|
@ -2427,9 +2441,11 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
|
|||
return std::nullopt;
|
||||
}};
|
||||
|
||||
// Probe the generic intrinsic function table first.
|
||||
// Probe the generic intrinsic function table first; allow for
|
||||
// the use of a legacy alias.
|
||||
parser::Messages genericBuffer;
|
||||
auto genericRange{genericFuncs_.equal_range(call.name)};
|
||||
const std::string &name{ResolveAlias(call.name)};
|
||||
auto genericRange{genericFuncs_.equal_range(name)};
|
||||
for (auto iter{genericRange.first}; iter != genericRange.second; ++iter) {
|
||||
if (auto specificCall{
|
||||
matchOrBufferMessages(*iter->second, genericBuffer)}) {
|
||||
|
|
|
@ -36,6 +36,7 @@ subroutine bozchecks
|
|||
! B) Argument to intrinsics listed from 16.9 below
|
||||
! BGE, BGT, BLE, BLT, CMPLX, DBLE, DSHIFTL,
|
||||
! DSHIFTR, IAND, IEOR, INT, IOR, MERGE_BITS, REAL
|
||||
! and legacy aliases AND, OR, XOR
|
||||
|
||||
! part A
|
||||
data f / Z"AA" / ! OK
|
||||
|
@ -63,16 +64,25 @@ subroutine bozchecks
|
|||
!ERROR: Typeless (BOZ) not allowed for both 'i=' & 'j=' arguments
|
||||
resint = IAND(B"0001", B"0011")
|
||||
resint = IAND(B"0001", 3)
|
||||
!ERROR: Typeless (BOZ) not allowed for both 'i=' & 'j=' arguments
|
||||
resint = AND(B"0001", B"0011")
|
||||
resint = AND(B"0001", 3)
|
||||
|
||||
!ERROR: Typeless (BOZ) not allowed for both 'i=' & 'j=' arguments
|
||||
resint = IEOR(B"0001", B"0011")
|
||||
resint = IEOR(B"0001", 3)
|
||||
!ERROR: Typeless (BOZ) not allowed for both 'i=' & 'j=' arguments
|
||||
resint = XOR(B"0001", B"0011")
|
||||
resint = XOR(B"0001", 3)
|
||||
|
||||
resint = INT(B"1010")
|
||||
|
||||
!ERROR: Typeless (BOZ) not allowed for both 'i=' & 'j=' arguments
|
||||
res = IOR(B"0101", B"0011")
|
||||
res = IOR(B"0101", 3)
|
||||
!ERROR: Typeless (BOZ) not allowed for both 'i=' & 'j=' arguments
|
||||
res = OR(B"0101", B"0011")
|
||||
res = OR(B"0101", 3)
|
||||
|
||||
res = MERGE_BITS(13,3,11)
|
||||
res = MERGE_BITS(B"1101",3,11)
|
||||
|
|
Loading…
Reference in New Issue