[flang] Accept %KIND type parameter inquiries on %RE,%IM, &c.

The x%KIND inquiry needs to be supported when 'x' is itself
a complex part reference or a type parameter inquiry.

Differential Revision: https://reviews.llvm.org/D123733
This commit is contained in:
Peter Klausler 2022-04-12 14:08:04 -07:00
parent de6e88ef5a
commit 9f5f2eb2a1
2 changed files with 19 additions and 8 deletions

View File

@ -1067,7 +1067,8 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) {
}
} else if (auto *details{sym->detailsIf<semantics::MiscDetails>()}) {
// special part-ref: %re, %im, %kind, %len
// Type errors are detected and reported in semantics.
// Type errors on the base of %re/%im/%len are detected and
// reported in name resolution.
using MiscKind = semantics::MiscDetails::Kind;
MiscKind kind{details->kind()};
if (kind == MiscKind::ComplexPartRe || kind == MiscKind::ComplexPartIm) {
@ -1088,7 +1089,6 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) {
}
} else if (kind == MiscKind::KindParamInquiry ||
kind == MiscKind::LenParamInquiry) {
// Convert x%KIND -> intrinsic KIND(x), x%LEN -> intrinsic LEN(x)
ActualArgument arg{std::move(*base)};
SetArgSourceLocation(arg, name);
return MakeFunctionRef(name, ActualArguments{std::move(arg)});

View File

@ -6431,6 +6431,18 @@ const parser::Name *DeclarationVisitor::FindComponent(
if (!base || !base->symbol) {
return nullptr;
}
if (auto *misc{base->symbol->detailsIf<MiscDetails>()}) {
if (component.source == "kind") {
if (misc->kind() == MiscDetails::Kind::ComplexPartRe ||
misc->kind() == MiscDetails::Kind::ComplexPartIm ||
misc->kind() == MiscDetails::Kind::KindParamInquiry ||
misc->kind() == MiscDetails::Kind::LenParamInquiry) {
// x%{re,im,kind,len}%kind
MakePlaceholder(component, MiscDetails::Kind::KindParamInquiry);
return &component;
}
}
}
auto &symbol{base->symbol->GetUltimate()};
if (!symbol.has<AssocEntityDetails>() && !ConvertToObjectEntity(symbol)) {
SayWithDecl(*base, symbol,
@ -6442,25 +6454,24 @@ const parser::Name *DeclarationVisitor::FindComponent(
return nullptr; // should have already reported error
}
if (const IntrinsicTypeSpec * intrinsic{type->AsIntrinsic()}) {
auto name{component.ToString()};
auto category{intrinsic->category()};
MiscDetails::Kind miscKind{MiscDetails::Kind::None};
if (name == "kind") {
if (component.source == "kind") {
miscKind = MiscDetails::Kind::KindParamInquiry;
} else if (category == TypeCategory::Character) {
if (name == "len") {
if (component.source == "len") {
miscKind = MiscDetails::Kind::LenParamInquiry;
}
} else if (category == TypeCategory::Complex) {
if (name == "re") {
if (component.source == "re") {
miscKind = MiscDetails::Kind::ComplexPartRe;
} else if (name == "im") {
} else if (component.source == "im") {
miscKind = MiscDetails::Kind::ComplexPartIm;
}
}
if (miscKind != MiscDetails::Kind::None) {
MakePlaceholder(component, miscKind);
return nullptr;
return &component;
}
} else if (const DerivedTypeSpec * derived{type->AsDerived()}) {
if (const Scope * scope{derived->scope()}) {