aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpeter klausler <pklausler@nvidia.com>2021-05-12 12:10:28 -0700
committerpeter klausler <pklausler@nvidia.com>2021-05-13 11:19:37 -0700
commit6829bd3ed0515e17c84c5e72fe1742bd20ee61e5 (patch)
treeccbfd0cf0de677c10a3f14084d42127321d4e00c
parentecc4e9e8f4cb7581cbc447bc838943176715695c (diff)
downloadllvm-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.h9
-rw-r--r--flang/lib/Evaluate/fold-designator.cpp18
-rw-r--r--flang/lib/Evaluate/tools.cpp12
-rw-r--r--flang/lib/Semantics/check-declarations.cpp11
-rw-r--r--flang/lib/Semantics/expression.cpp7
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