diff options
author | peter klausler <pklausler@nvidia.com> | 2021-05-12 12:10:28 -0700 |
---|---|---|
committer | peter klausler <pklausler@nvidia.com> | 2021-05-13 11:19:37 -0700 |
commit | 6829bd3ed0515e17c84c5e72fe1742bd20ee61e5 (patch) | |
tree | ccbfd0cf0de677c10a3f14084d42127321d4e00c | |
parent | ecc4e9e8f4cb7581cbc447bc838943176715695c (diff) | |
download | llvm-6829bd3ed0515e17c84c5e72fe1742bd20ee61e5.zip llvm-6829bd3ed0515e17c84c5e72fe1742bd20ee61e5.tar.gz llvm-6829bd3ed0515e17c84c5e72fe1742bd20ee61e5.tar.bz2 |
[flang] (NFC) Expose internal idiom as utility API
Add overloads to AsGenericExpr() in Evaluate/tools.h to take care
of wrapping an untyped DataRef or bare Symbol in a typed Designator
wrapped up in a generic Expr<SomeType>. Use the new overloads to
replace a few instances of code that was calling TypedWrapper<>()
with a dynamic type.
This new tool will be useful in lowering to drive some code that
works with typed expressions (viz., list-directed I/O list items)
when starting with only a bare Symbol (viz., NAMELIST).
Differential Revision: https://reviews.llvm.org/D102352
-rw-r--r-- | flang/include/flang/Evaluate/tools.h | 9 | ||||
-rw-r--r-- | flang/lib/Evaluate/fold-designator.cpp | 18 | ||||
-rw-r--r-- | flang/lib/Evaluate/tools.cpp | 12 | ||||
-rw-r--r-- | flang/lib/Semantics/check-declarations.cpp | 11 | ||||
-rw-r--r-- | flang/lib/Semantics/expression.cpp | 7 |
5 files changed, 35 insertions, 22 deletions
diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h index 7cb1139..6adfe04 100644 --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -115,14 +115,19 @@ common::IfNoLvalue<Expr<SomeType>, A> AsGenericExpr(A &&x) { } } +inline Expr<SomeType> AsGenericExpr(Expr<SomeType> &&x) { return std::move(x); } + +// These overloads wrap DataRefs and simple whole variables up into +// generic expressions if they have a known type. +std::optional<Expr<SomeType>> AsGenericExpr(DataRef &&); +std::optional<Expr<SomeType>> AsGenericExpr(const Symbol &); + template <typename A> common::IfNoLvalue<Expr<SomeKind<ResultType<A>::category>>, A> AsCategoryExpr( A &&x) { return Expr<SomeKind<ResultType<A>::category>>{AsExpr(std::move(x))}; } -inline Expr<SomeType> AsGenericExpr(Expr<SomeType> &&x) { return std::move(x); } - Expr<SomeType> Parenthesize(Expr<SomeType> &&); Expr<SomeReal> GetComplexPart( diff --git a/flang/lib/Evaluate/fold-designator.cpp b/flang/lib/Evaluate/fold-designator.cpp index dea8a43..c4f072e 100644 --- a/flang/lib/Evaluate/fold-designator.cpp +++ b/flang/lib/Evaluate/fold-designator.cpp @@ -312,12 +312,12 @@ std::optional<Expr<SomeType>> OffsetToDesignator(FoldingContext &context, if (std::optional<DataRef> dataRef{ OffsetToDataRef(context, NamedEntity{baseSymbol}, offset, size)}) { const Symbol &symbol{dataRef->GetLastSymbol()}; - if (auto type{DynamicType::From(symbol)}) { - if (std::optional<Expr<SomeType>> result{ - TypedWrapper<Designator>(*type, std::move(*dataRef))}) { - if (IsAllocatableOrPointer(symbol)) { - } else if (auto elementBytes{ - ToInt64(type->MeasureSizeInBytes(context, true))}) { + if (std::optional<Expr<SomeType>> result{ + AsGenericExpr(std::move(*dataRef))}) { + if (IsAllocatableOrPointer(symbol)) { + } else if (auto type{DynamicType::From(symbol)}) { + if (auto elementBytes{ + ToInt64(type->MeasureSizeInBytes(context, true))}) { if (auto *zExpr{std::get_if<Expr<SomeComplex>>(&result->u)}) { if (size * 2 > static_cast<std::size_t>(*elementBytes)) { return result; @@ -351,9 +351,9 @@ std::optional<Expr<SomeType>> OffsetToDesignator(FoldingContext &context, } } } - if (offset == 0) { - return result; - } + } + if (offset == 0) { + return result; } } } diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp index a0057e89..e37db52 100644 --- a/flang/lib/Evaluate/tools.cpp +++ b/flang/lib/Evaluate/tools.cpp @@ -19,6 +19,18 @@ using namespace Fortran::parser::literals; namespace Fortran::evaluate { +std::optional<Expr<SomeType>> AsGenericExpr(DataRef &&ref) { + const Symbol &symbol{ref.GetLastSymbol()}; + if (auto dyType{DynamicType::From(symbol)}) { + return TypedWrapper<Designator, DataRef>(*dyType, std::move(ref)); + } + return std::nullopt; +} + +std::optional<Expr<SomeType>> AsGenericExpr(const Symbol &symbol) { + return AsGenericExpr(DataRef{symbol}); +} + Expr<SomeType> Parenthesize(Expr<SomeType> &&expr) { return std::visit( [&](auto &&x) { diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp index 0e9d4da..7e83ccf 100644 --- a/flang/lib/Semantics/check-declarations.cpp +++ b/flang/lib/Semantics/check-declarations.cpp @@ -538,13 +538,10 @@ void CheckHelper::CheckPointerInitialization(const Symbol &symbol) { !scopeIsUninstantiatedPDT_) { if (const auto *object{symbol.detailsIf<ObjectEntityDetails>()}) { if (object->init()) { // C764, C765; C808 - if (auto dyType{evaluate::DynamicType::From(symbol)}) { - if (auto designator{evaluate::TypedWrapper<evaluate::Designator>( - *dyType, evaluate::DataRef{symbol})}) { - auto restorer{messages_.SetLocation(symbol.name())}; - context_.set_location(symbol.name()); - CheckInitialTarget(foldingContext_, *designator, *object->init()); - } + if (auto designator{evaluate::AsGenericExpr(symbol)}) { + auto restorer{messages_.SetLocation(symbol.name())}; + context_.set_location(symbol.name()); + CheckInitialTarget(foldingContext_, *designator, *object->init()); } } } else if (const auto *proc{symbol.detailsIf<ProcEntityDetails>()}) { diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp index b67f52c..86780e3 100644 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -195,12 +195,11 @@ MaybeExpr ExpressionAnalyzer::Designate(DataRef &&ref) { } else { Say("'%s' is not a specific intrinsic procedure"_err_en_US, symbol.name()); - return std::nullopt; } - } else if (auto dyType{DynamicType::From(symbol)}) { - return TypedWrapper<Designator, DataRef>(*dyType, std::move(ref)); + return std::nullopt; + } else { + return AsGenericExpr(std::move(ref)); } - return std::nullopt; } // Some subscript semantic checks must be deferred until all of the |