// Predicate: true when an expression is a coarray (corank > 0)
bool IsCoarray(const ActualArgument &);
+bool IsCoarray(const Symbol &);
template <typename A> bool IsCoarray(const A &) { return false; }
template <typename A> bool IsCoarray(const Designator<A> &designator) {
if (const auto *symbol{std::get_if<SymbolRef>(&designator.u)}) {
- return symbol->get().Corank() > 0;
+ return IsCoarray(**symbol);
}
return false;
}
bool IsProcedure(const Scope &);
bool IsProcedurePointer(const Symbol &);
bool IsAutomatic(const Symbol &);
-bool IsCoarray(const Symbol &);
bool IsSaved(const Symbol &); // saved implicitly or explicitly
bool IsDummy(const Symbol &);
bool IsFunctionResult(const Symbol &);
}
bool IsCoarray(const ActualArgument &arg) {
- if (const auto *expr{arg.UnwrapExpr()}) {
- return IsCoarray(*expr);
- }
- return false;
+ const auto *expr{arg.UnwrapExpr()};
+ return expr && IsCoarray(*expr);
+}
+
+bool IsCoarray(const Symbol &symbol) {
+ return GetAssociationRoot(symbol).Corank() > 0;
}
bool IsProcedure(const Expr<SomeType> &expr) {
return false;
}
-bool IsCoarray(const Symbol &symbol) {
- return GetAssociationRoot(symbol).Corank() > 0;
-}
-
bool IsSaved(const Symbol &original) {
const Symbol &symbol{GetAssociationRoot(original)};
const Scope &scope{symbol.owner()};
return false;
} else if (scopeKind == Scope::Kind::Module ||
(scopeKind == Scope::Kind::MainProgram &&
- (symbol.attrs().test(Attr::TARGET) || IsCoarray(symbol)))) {
+ (symbol.attrs().test(Attr::TARGET) || evaluate::IsCoarray(symbol)))) {
// 8.5.16p4
// In main programs, implied SAVE matters only for pointer
// initialization targets and coarrays.
CHECK(context.AnyFatalError());
return false;
}
- if (IsCoarray(*symbol_)) {
+ if (evaluate::IsCoarray(*symbol_)) {
if (allocateInfo_.gotTypeSpec) {
// C938
if (const DerivedTypeSpec *
messages_.Say(
"VALUE attribute may not apply to an assumed-size array"_err_en_US);
}
- if (IsCoarray(symbol)) {
+ if (evaluate::IsCoarray(symbol)) {
messages_.Say("VALUE attribute may not apply to a coarray"_err_en_US);
}
if (IsAllocatable(symbol)) {
"Assumed-type argument '%s' cannot be INTENT(OUT)"_err_en_US,
symbol.name());
}
- if (IsCoarray(symbol)) {
+ if (evaluate::IsCoarray(symbol)) {
messages_.Say(
"Assumed-type argument '%s' cannot be a coarray"_err_en_US,
symbol.name());
if (details.isDummy()) {
if (symbol.attrs().test(Attr::INTENT_OUT)) {
if (FindUltimateComponent(symbol, [](const Symbol &x) {
- return IsCoarray(x) && IsAllocatable(x);
+ return evaluate::IsCoarray(x) && IsAllocatable(x);
})) { // C846
messages_.Say(
"An INTENT(OUT) dummy argument may not be, or contain, an ALLOCATABLE coarray"_err_en_US);
messages_.Say(
"A dummy argument of an ELEMENTAL procedure may not be ALLOCATABLE"_err_en_US);
}
- if (IsCoarray(symbol)) {
+ if (evaluate::IsCoarray(symbol)) {
messages_.Say(
"A dummy argument of an ELEMENTAL procedure may not be a coarray"_err_en_US);
}
}
if (symbol.has<UseDetails>() || symbol.has<HostAssocDetails>()) {
const Symbol &ultimate{symbol.GetUltimate()};
- if (IsCoarray(ultimate)) {
+ if (evaluate::IsCoarray(ultimate)) {
messages_.Say(
"VOLATILE attribute may not apply to a coarray accessed by USE or host association"_err_en_US);
}
// Predicate for deallocations caused by intrinsic assignment
static bool DeallocateNonCoarray(const Symbol &component) {
- return !IsCoarray(component);
+ return !evaluate::IsCoarray(component);
}
static bool WillDeallocatePolymorphic(const Symbol &entity,
"Finalizable variable '%s' not allowed in a locality-spec"_err_en_US);
return false;
}
- if (IsCoarray(symbol)) { // C1128
+ if (evaluate::IsCoarray(symbol)) { // C1128
SayWithDecl(
name, symbol, "Coarray '%s' not allowed in a locality-spec"_err_en_US);
return false;
private:
bool IsCoarrayObject(const parser::AllocateObject &allocateObject) {
const parser::Name &name{GetLastName(allocateObject)};
- return name.symbol && IsCoarray(*name.symbol);
+ return name.symbol && evaluate::IsCoarray(*name.symbol);
}
};
bool HasCoarray(const parser::Expr &expression) {
if (const auto *expr{GetExpr(expression)}) {
for (const Symbol &symbol : evaluate::CollectSymbols(*expr)) {
- if (IsCoarray(GetAssociationRoot(symbol))) {
+ if (evaluate::IsCoarray(symbol)) {
return true;
}
}
UltimateComponentIterator::const_iterator FindCoarrayUltimateComponent(
const DerivedTypeSpec &derived) {
UltimateComponentIterator ultimates{derived};
- return std::find_if(ultimates.begin(), ultimates.end(), IsCoarray);
+ return std::find_if(ultimates.begin(), ultimates.end(),
+ [](const Symbol &symbol) { return evaluate::IsCoarray(symbol); });
}
UltimateComponentIterator::const_iterator FindPointerUltimateComponent(
const DerivedTypeSpec &derived) {
UltimateComponentIterator ultimates{derived};
return std::find_if(ultimates.begin(), ultimates.end(), [](const Symbol &x) {
- return IsPolymorphicAllocatable(x) && !IsCoarray(x);
+ return IsPolymorphicAllocatable(x) && !evaluate::IsCoarray(x);
});
}