From 9f5f2eb2a1085d49afbf9e6912086c6a3b5e6a95 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Tue, 12 Apr 2022 14:08:04 -0700 Subject: [PATCH] [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 --- flang/lib/Semantics/expression.cpp | 4 ++-- flang/lib/Semantics/resolve-names.cpp | 23 +++++++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index e276fbb..bb8e6a5 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -1067,7 +1067,8 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) { } } else if (auto *details{sym->detailsIf()}) { // 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)}); diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index 85b5f3a..8fd25bd 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -6431,6 +6431,18 @@ const parser::Name *DeclarationVisitor::FindComponent( if (!base || !base->symbol) { return nullptr; } + if (auto *misc{base->symbol->detailsIf()}) { + 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() && !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()}) { -- 2.7.4