From 74563c17c13b5559936711456c3febc788c36ddb Mon Sep 17 00:00:00 2001 From: peter klausler Date: Wed, 12 Sep 2018 16:27:51 -0700 Subject: [PATCH] [flang] Add "explicit" to constructors, define Type Original-commit: flang-compiler/f18@79c165af65a0357f5bf90995f862fdb4ec11364e Reviewed-on: https://github.com/flang-compiler/f18/pull/183 Tree-same-pre-rewrite: false --- flang/lib/evaluate/CMakeLists.txt | 36 ++++++--------- flang/lib/evaluate/expression.cc | 8 ++-- flang/lib/evaluate/expression.h | 90 +++++++++++++++++++++++-------------- flang/lib/evaluate/tools.cc | 93 +++++++++++++++++++++------------------ flang/lib/evaluate/tools.h | 48 ++++++++++---------- flang/lib/evaluate/type.cc | 25 +++++++++++ flang/lib/evaluate/type.h | 58 +++++++++++++++++++----- flang/lib/evaluate/variable.cc | 7 +-- flang/lib/semantics/expression.cc | 3 +- 9 files changed, 229 insertions(+), 139 deletions(-) create mode 100644 flang/lib/evaluate/type.cc diff --git a/flang/lib/evaluate/CMakeLists.txt b/flang/lib/evaluate/CMakeLists.txt index 33fd65c..163e57a 100644 --- a/flang/lib/evaluate/CMakeLists.txt +++ b/flang/lib/evaluate/CMakeLists.txt @@ -1,28 +1,18 @@ -# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +#Copyright(c) 2018, NVIDIA CORPORATION.All rights reserved. # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at +#Licensed under the Apache License, Version 2.0(the "License"); +#you may not use this file except in compliance with the License. +#You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +#http: // www.apache.org/licenses/LICENSE-2.0 # -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +#Unless required by applicable law or agreed to in writing, software +#distributed under the License is distributed on an "AS IS" BASIS, +#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +#See the License for the specific language governing permissions and +#limitations under the License. -add_library(FortranEvaluate - common.cc - complex.cc - expression.cc - integer.cc - logical.cc - real.cc - tools.cc - variable.cc -) +add_library(FortranEvaluate common.cc complex.cc expression.cc integer + .cc logical.cc real.cc tools.cc type.cc variable.cc) -target_link_libraries(FortranEvaluate - FortranCommon -) + target_link_libraries(FortranEvaluate FortranCommon) diff --git a/flang/lib/evaluate/expression.cc b/flang/lib/evaluate/expression.cc index 1f2deca..1904daf 100644 --- a/flang/lib/evaluate/expression.cc +++ b/flang/lib/evaluate/expression.cc @@ -76,14 +76,14 @@ auto ExpressionBase::Fold(FoldingContext &context) // Folding may have produced a constant of some // dissimilar LOGICAL kind. bool truth{c->value.IsTrue()}; - derived() = truth; + derived() = Derived{truth}; return {Const{truth}}; } if constexpr (std::is_same_v, Thing>) { // Preserve parentheses around constants. - derived() = Thing{Derived{*c}}; + derived() = Derived{Thing{Derived{*c}}}; } else { - derived() = *c; + derived() = Derived{*c}; } return {Const{c->value}}; } @@ -519,6 +519,8 @@ auto ExpressionBase::ScalarValue() const [](const BOZLiteralConstant &) -> std::optional> { return std::nullopt; }, + [](const Expr> &) + -> std::optional> { return std::nullopt; }, [](const auto &catEx) -> std::optional> { if (auto cv{catEx.ScalarValue()}) { // *cv is SomeKindScalar for some category; rewrap it. diff --git a/flang/lib/evaluate/expression.h b/flang/lib/evaluate/expression.h index 30cc75b..339e825 100644 --- a/flang/lib/evaluate/expression.h +++ b/flang/lib/evaluate/expression.h @@ -121,8 +121,8 @@ private: public: CLASS_BOILERPLATE(Operation) - Operation(const Expr &... x) : operand_{x...} {} - Operation(Expr &&... x) + explicit Operation(const Expr &... x) : operand_{x...} {} + explicit Operation(Expr &&... x) : operand_{std::forward>(x)...} {} Derived &derived() { return *static_cast(this); } @@ -431,13 +431,14 @@ public: // TODO: R916 type-param-inquiry CLASS_BOILERPLATE(Expr) - Expr(const Scalar &x) : u{Constant{x}} {} - Expr(std::int64_t n) : u{Constant{n}} {} - Expr(std::uint64_t n) : u{Constant{n}} {} - Expr(int n) : u{Constant{n}} {} - template Expr(const A &x) : u{x} {} + explicit Expr(const Scalar &x) : u{Constant{x}} {} + explicit Expr(std::int64_t n) : u{Constant{n}} {} + explicit Expr(std::uint64_t n) : u{Constant{n}} {} + explicit Expr(int n) : u{Constant{n}} {} + template explicit Expr(const A &x) : u{x} {} template - Expr(std::enable_if_t, A> &&x) : u(std::move(x)) {} + explicit Expr(std::enable_if_t, A> &&x) + : u(std::move(x)) {} private: using Conversions = std::variant, @@ -460,10 +461,11 @@ public: using IsFoldableTrait = std::true_type; CLASS_BOILERPLATE(Expr) - Expr(const Scalar &x) : u{Constant{x}} {} - template Expr(const A &x) : u{x} {} + explicit Expr(const Scalar &x) : u{Constant{x}} {} + template explicit Expr(const A &x) : u{x} {} template - Expr(std::enable_if_t, A> &&x) : u{std::move(x)} {} + explicit Expr(std::enable_if_t, A> &&x) + : u{std::move(x)} {} private: // N.B. Real->Complex and Complex->Real conversions are done with CMPLX @@ -488,10 +490,11 @@ public: using Result = Type; using IsFoldableTrait = std::true_type; CLASS_BOILERPLATE(Expr) - Expr(const Scalar &x) : u{Constant{x}} {} - template Expr(const A &x) : u{x} {} + explicit Expr(const Scalar &x) : u{Constant{x}} {} + template explicit Expr(const A &x) : u{x} {} template - Expr(std::enable_if_t, A> &&x) : u{std::move(x)} {} + explicit Expr(std::enable_if_t, A> &&x) + : u{std::move(x)} {} // Note that many COMPLEX operations are represented as REAL operations // over their components (viz., conversions, negation, add, and subtract). @@ -528,12 +531,14 @@ public: using Result = Type; using IsFoldableTrait = std::true_type; CLASS_BOILERPLATE(Expr) - Expr(const Scalar &x) : u{Constant{x}} {} - Expr(Scalar &&x) : u{Constant{std::move(x)}} {} - template Expr(const A &x) : u{x} {} + explicit Expr(const Scalar &x) : u{Constant{x}} {} + explicit Expr(Scalar &&x) : u{Constant{std::move(x)}} {} + template explicit Expr(const A &x) : u{x} {} + template + explicit Expr(std::enable_if_t, A> &&x) + : u{std::move(x)} {} template - Expr(std::enable_if_t, A> &&x) : u{std::move(x)} {} - template Expr(CopyableIndirection &&x) : u{std::move(x)} {} + explicit Expr(CopyableIndirection &&x) : u{std::move(x)} {} Expr LEN() const; @@ -583,9 +588,9 @@ template<> class Relational { public: using Result = LogicalResult; CLASS_BOILERPLATE(Relational) - template Relational(const A &x) : u(x) {} + template explicit Relational(const A &x) : u(x) {} template - Relational(std::enable_if_t, A> &&x) + explicit Relational(std::enable_if_t, A> &&x) : u{std::move(x)} {} std::ostream &Dump(std::ostream &o) const; common::MapTemplate u; @@ -613,11 +618,12 @@ public: using Result = Type; using IsFoldableTrait = std::true_type; CLASS_BOILERPLATE(Expr) - Expr(const Scalar &x) : u{Constant{x}} {} - Expr(bool x) : u{Constant{x}} {} - template Expr(const A &x) : u(x) {} + explicit Expr(const Scalar &x) : u{Constant{x}} {} + explicit Expr(bool x) : u{Constant{x}} {} + template explicit Expr(const A &x) : u(x) {} template - Expr(std::enable_if_t, A> &&x) : u{std::move(x)} {} + explicit Expr(std::enable_if_t, A> &&x) + : u{std::move(x)} {} private: using Operations = std::variant, @@ -634,6 +640,22 @@ extern template class Expr>; extern template class Expr>; extern template class Expr>; +template<> +class Expr> + : public ExpressionBase> { +public: + using Result = Type; + using IsFoldableTrait = std::false_type; + CLASS_BOILERPLATE(Expr) + template + explicit Expr(const Result &r, const A &x) : result{r}, u{x} {} + template + explicit Expr(Result &&r, std::enable_if_t, A> &&x) + : result{std::move(r)}, u{std::move(x)} {} + Result result; + std::variant, FunctionReference> u; +}; + // A polymorphic expression of known intrinsic type category, but dynamic // kind, represented as a discriminated union over Expr> // for each supported kind K in the category. @@ -644,9 +666,10 @@ public: using IsFoldableTrait = std::true_type; CLASS_BOILERPLATE(Expr) - template Expr(const A &x) : u{x} {} + template explicit Expr(const A &x) : u{x} {} template - Expr(std::enable_if_t, A> &&x) : u{std::move(x)} {} + explicit Expr(std::enable_if_t, A> &&x) + : u{std::move(x)} {} common::MapTemplate> u; }; @@ -664,15 +687,17 @@ public: // its destructor is externalized to reduce redundant default instances. ~Expr(); - template Expr(const A &x) : u{x} {} + template explicit Expr(const A &x) : u{x} {} template - Expr(std::enable_if_t, A> &&x) : u{std::move(x)} {} + explicit Expr(std::enable_if_t, A> &&x) + : u{std::move(x)} {} template - Expr(const Expr> &x) : u{Expr>{x}} {} + explicit Expr(const Expr> &x) : u{Expr>{x}} {} template - Expr(Expr> &&x) : u{Expr>{std::move(x)}} {} + explicit Expr(Expr> &&x) + : u{Expr>{std::move(x)}} {} template Expr &operator=(const Expr> &x) { @@ -686,7 +711,8 @@ public: return *this; } - using Others = std::variant; + using Others = + std::variant>>; using Categories = common::MapTemplate; common::CombineVariants u; }; diff --git a/flang/lib/evaluate/tools.cc b/flang/lib/evaluate/tools.cc index fb85185..45fdb74 100644 --- a/flang/lib/evaluate/tools.cc +++ b/flang/lib/evaluate/tools.cc @@ -27,14 +27,15 @@ ConvertRealOperandsResult ConvertRealOperands( parser::ContextualMessages &messages, Expr &&x, Expr &&y) { return std::visit( - common::visitors{[&](Expr &&ix, Expr &&iy) - -> ConvertRealOperandsResult { - // Can happen in a CMPLX() constructor. Per F'2018, - // both integer operands are converted to default REAL. - return {AsSameKindExprs( - ConvertToType(std::move(ix)), - ConvertToType(std::move(iy)))}; - }, + common::visitors{ + [&](Expr &&ix, + Expr &&iy) -> ConvertRealOperandsResult { + // Can happen in a CMPLX() constructor. Per F'2018, + // both integer operands are converted to default REAL. + return {AsSameKindExprs( + AsCategoryExpr(ConvertToType(std::move(ix))), + AsCategoryExpr(ConvertToType(std::move(iy))))}; + }, [&](Expr &&ix, Expr &&ry) -> ConvertRealOperandsResult { return {AsSameKindExprs( @@ -53,14 +54,14 @@ ConvertRealOperandsResult ConvertRealOperands( [&](Expr &&ix, BOZLiteralConstant &&by) -> ConvertRealOperandsResult { return {AsSameKindExprs( - ConvertToType(std::move(ix)), - ConvertToType(std::move(by)))}; + AsCategoryExpr(ConvertToType(std::move(ix))), + AsCategoryExpr(ConvertToType(std::move(by))))}; }, [&](BOZLiteralConstant &&bx, Expr &&iy) -> ConvertRealOperandsResult { return {AsSameKindExprs( - ConvertToType(std::move(bx)), - ConvertToType(std::move(iy)))}; + AsCategoryExpr(ConvertToType(std::move(bx))), + AsCategoryExpr(ConvertToType(std::move(iy))))}; }, [&](Expr &&rx, BOZLiteralConstant &&by) -> ConvertRealOperandsResult { @@ -285,20 +286,20 @@ std::optional> NumericOperation( }, // Operations with one typeless operand [&](BOZLiteralConstant &&bx, Expr &&iy) { - return NumericOperation( - messages, ConvertTo(iy, std::move(bx)), std::move(y)); + return NumericOperation(messages, + AsGenericExpr(ConvertTo(iy, std::move(bx))), std::move(y)); }, [&](BOZLiteralConstant &&bx, Expr &&ry) { - return NumericOperation( - messages, ConvertTo(ry, std::move(bx)), std::move(y)); + return NumericOperation(messages, + AsGenericExpr(ConvertTo(ry, std::move(bx))), std::move(y)); }, [&](Expr &&ix, BOZLiteralConstant &&by) { - return NumericOperation( - messages, std::move(x), ConvertTo(ix, std::move(by))); + return NumericOperation(messages, std::move(x), + AsGenericExpr(ConvertTo(ix, std::move(by)))); }, [&](Expr &&rx, BOZLiteralConstant &&by) { - return NumericOperation( - messages, std::move(x), ConvertTo(rx, std::move(by))); + return NumericOperation(messages, std::move(x), + AsGenericExpr(ConvertTo(rx, std::move(by)))); }, // Default case [&](auto &&, auto &&) { @@ -323,11 +324,11 @@ template std::optional> NumericOperation( std::optional> Negation( parser::ContextualMessages &messages, Expr &&x) { return std::visit( - common::visitors{[&](BOZLiteralConstant &&) { - messages.Say( - "BOZ literal cannot be negated"_err_en_US); - return NoExpr(); - }, + common::visitors{ + [&](BOZLiteralConstant &&) { + messages.Say("BOZ literal cannot be negated"_err_en_US); + return NoExpr(); + }, [&](Expr &&x) { return Package(std::move(x)); }, [&](Expr &&x) { return Package(-std::move(x)); }, [&](Expr &&x) { return Package(-std::move(x)); }, @@ -340,7 +341,13 @@ std::optional> Negation( // TODO: defined operator messages.Say("LOGICAL cannot be negated"_err_en_US); return NoExpr(); - }}, + }, + [&](Expr> &&x) { + // TODO: defined operator + messages.Say("derived type cannot be negated"_err_en_US); + return NoExpr(); + }, + }, std::move(x.u)); } @@ -383,12 +390,12 @@ std::optional> Relate(parser::ContextualMessages &messages, PromoteAndRelate(opr, std::move(rx), std::move(ry))); }, [&](Expr &&rx, Expr &&iy) { - return Relate( - messages, opr, std::move(x), ConvertTo(rx, std::move(iy))); + return Relate(messages, opr, std::move(x), + AsGenericExpr(ConvertTo(rx, std::move(iy)))); }, [&](Expr &&ix, Expr &&ry) { - return Relate( - messages, opr, ConvertTo(ry, std::move(ix)), std::move(y)); + return Relate(messages, opr, + AsGenericExpr(ConvertTo(ry, std::move(ix))), std::move(y)); }, [&](Expr &&zx, Expr &&zy) { if (opr != RelationalOperator::EQ && @@ -397,10 +404,12 @@ std::optional> Relate(parser::ContextualMessages &messages, "COMPLEX data may be compared only for equality"_err_en_US); return std::optional>{}; } else { - auto rr{Relate(messages, opr, GetComplexPart(zx, false), - GetComplexPart(zy, false))}; - auto ri{Relate(messages, opr, GetComplexPart(zx, true), - GetComplexPart(zy, true))}; + auto rr{Relate(messages, opr, + AsGenericExpr(GetComplexPart(zx, false)), + AsGenericExpr(GetComplexPart(zy, false)))}; + auto ri{ + Relate(messages, opr, AsGenericExpr(GetComplexPart(zx, true)), + AsGenericExpr(GetComplexPart(zy, true)))}; if (auto parts{ common::AllPresent(std::move(rr), std::move(ri))}) { // (a,b)==(c,d) -> (a==c) .AND. (b==d) @@ -418,20 +427,20 @@ std::optional> Relate(parser::ContextualMessages &messages, } }, [&](Expr &&zx, Expr &&iy) { - return Relate( - messages, opr, std::move(x), ConvertTo(zx, std::move(iy))); + return Relate(messages, opr, std::move(x), + AsGenericExpr(ConvertTo(zx, std::move(iy)))); }, [&](Expr &&zx, Expr &&ry) { - return Relate( - messages, opr, std::move(x), ConvertTo(zx, std::move(ry))); + return Relate(messages, opr, std::move(x), + AsGenericExpr(ConvertTo(zx, std::move(ry)))); }, [&](Expr &&ix, Expr &&zy) { - return Relate( - messages, opr, ConvertTo(zy, std::move(ix)), std::move(y)); + return Relate(messages, opr, + AsGenericExpr(ConvertTo(zy, std::move(ix))), std::move(y)); }, [&](Expr &&rx, Expr &&zy) { - return Relate( - messages, opr, ConvertTo(zy, std::move(rx)), std::move(y)); + return Relate(messages, opr, + AsGenericExpr(ConvertTo(zy, std::move(rx))), std::move(y)); }, [&](Expr &&cx, Expr &&cy) { return std::visit( diff --git a/flang/lib/evaluate/tools.h b/flang/lib/evaluate/tools.h index fa331bf..afab368 100644 --- a/flang/lib/evaluate/tools.h +++ b/flang/lib/evaluate/tools.h @@ -28,12 +28,12 @@ namespace Fortran::evaluate { // specific types and wrap them in Expr<> containers of more abstract types. template Expr> AsExpr(A &&x) { - return {std::move(x)}; + return Expr>{std::move(x)}; } template Expr> AsCategoryExpr(Expr> &&x) { - return {std::move(x)}; + return Expr>{std::move(x)}; } template @@ -47,12 +47,12 @@ Expr> AsCategoryExpr(SomeKindScalar &&x) { } template Expr AsGenericExpr(A &&x) { - return {std::move(x)}; + return Expr{std::move(x)}; } template Expr AsGenericExpr(Expr> &&x) { - return {AsCategoryExpr(std::move(x))}; + return Expr{AsCategoryExpr(std::move(x))}; } template<> inline Expr AsGenericExpr(Constant &&x) { @@ -96,10 +96,10 @@ Expr ConvertToType(Expr> &&x) { if constexpr (TO::category == TypeCategory::Complex) { using Part = typename TO::Part; Scalar zero; - return {ComplexConstructor{ + return Expr{ComplexConstructor{ ConvertToType(std::move(x)), Expr{Constant{zero}}}}; } else { - return {Convert{std::move(x)}}; + return Expr{Convert{std::move(x)}}; } } else { // Same type category @@ -108,8 +108,8 @@ Expr ConvertToType(Expr> &&x) { } if constexpr (TO::category == TypeCategory::Complex) { // Extract, convert, and recombine the components. - return {std::visit( - [](auto &z) -> ComplexConstructor { + return Expr{std::visit( + [](auto &z) { using FromType = ResultType; using FromPart = typename FromType::Part; using FromGeneric = SomeKind; @@ -118,11 +118,12 @@ Expr ConvertToType(Expr> &&x) { Expr{ComplexComponent{false, z}}}}; Convert im{Expr{ Expr{ComplexComponent{true, z}}}}; - return {std::move(re), std::move(im)}; + return ComplexConstructor{ + AsExpr(std::move(re)), AsExpr(std::move(im))}; }, x.u)}; } else { - return {Convert{std::move(x)}}; + return Expr{Convert{std::move(x)}}; } } } @@ -148,7 +149,7 @@ Expr> ConvertTo( template Expr> ConvertTo( const Expr> &, Expr> &&x) { - return ConvertToType>(AsCategoryExpr(std::move(x))); + return AsExpr(ConvertToType>(AsCategoryExpr(std::move(x)))); } template @@ -264,11 +265,11 @@ Expr Combine(Expr &&x, Expr &&y) { std::is_same_v, Subtract>)) { static constexpr int kind{SPECIFIC::kind}; using Part = Type; - return AsExpr( - ComplexConstructor{OPR{ComplexComponent{false, x}, - ComplexComponent{false, y}}, - OPR{ComplexComponent{true, x}, - ComplexComponent{true, y}}}); + return AsExpr(ComplexConstructor{ + AsExpr(OPR{AsExpr(ComplexComponent{false, x}), + AsExpr(ComplexComponent{false, y})}), + AsExpr(OPR{AsExpr(ComplexComponent{true, x}), + AsExpr(ComplexComponent{true, y})})}); } else { return AsExpr(OPR{std::move(x), std::move(y)}); } @@ -329,35 +330,36 @@ Expr BinaryLogicalOperation( template Expr> operator-(Expr> &&x) { - return {Negate>{std::move(x)}}; + return AsExpr(Negate>{std::move(x)}); } template Expr> operator-( Expr> &&x) { using Part = Type; - return {ComplexConstructor{Negate{ComplexComponent{false, x}}, - Negate{ComplexComponent{true, x}}}}; + return AsExpr(ComplexConstructor{ + AsExpr(Negate{AsExpr(ComplexComponent{false, x})}), + AsExpr(Negate{AsExpr(ComplexComponent{true, x})})}); } template Expr> operator+(Expr> &&x, Expr> &&y) { - return {Combine>(std::move(x), std::move(y))}; + return AsExpr(Combine>(std::move(x), std::move(y))); } template Expr> operator-(Expr> &&x, Expr> &&y) { - return {Combine>(std::move(x), std::move(y))}; + return AsExpr(Combine>(std::move(x), std::move(y))); } template Expr> operator*(Expr> &&x, Expr> &&y) { - return {Combine>(std::move(x), std::move(y))}; + return AsExpr(Combine>(std::move(x), std::move(y))); } template Expr> operator/(Expr> &&x, Expr> &&y) { - return {Combine>(std::move(x), std::move(y))}; + return AsExpr(Combine>(std::move(x), std::move(y))); } template Expr> operator-(Expr> &&x) { diff --git a/flang/lib/evaluate/type.cc b/flang/lib/evaluate/type.cc new file mode 100644 index 0000000..2ee4db5a --- /dev/null +++ b/flang/lib/evaluate/type.cc @@ -0,0 +1,25 @@ +// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "type.h" +#include "../semantics/type.h" +#include + +using namespace std::literals::string_literals; + +namespace Fortran::evaluate { +std::string Type::Dump() const { + return "TYPE("s + spec().name().ToString() + ')'; +} +} // namespace Fortran::evaluate diff --git a/flang/lib/evaluate/type.h b/flang/lib/evaluate/type.h index 889c897..746c39e 100644 --- a/flang/lib/evaluate/type.h +++ b/flang/lib/evaluate/type.h @@ -22,6 +22,7 @@ // are suitable for use as template parameters to instantiate other class // templates, like expressions, over the supported types and kinds. +#include "common.h" #include "complex.h" #include "integer.h" #include "logical.h" @@ -34,13 +35,17 @@ #include #include +namespace Fortran::semantics { +class DerivedTypeSpec; +} // namespace Fortran::semantics + namespace Fortran::evaluate { using common::TypeCategory; // Specific intrinsic types are represented by specializations of // this class template Type. -template struct Type; +template class Type; template struct TypeBase { static constexpr bool isSpecificType{true}; @@ -52,71 +57,100 @@ template struct TypeBase { }; template -struct Type +class Type : public TypeBase { +public: using Scalar = value::Integer<8 * KIND>; }; template<> -struct Type : public TypeBase { +class Type : public TypeBase { +public: using Scalar = value::Real::Scalar, 11>; }; template<> -struct Type : public TypeBase { +class Type : public TypeBase { +public: using Scalar = value::Real::Scalar, 24>; }; template<> -struct Type : public TypeBase { +class Type : public TypeBase { +public: using Scalar = value::Real::Scalar, 53>; }; template<> -struct Type : public TypeBase { +class Type : public TypeBase { +public: using Scalar = value::Real, 64, false>; }; template<> -struct Type : public TypeBase { +class Type : public TypeBase { +public: using Scalar = value::Real, 112>; }; // The KIND type parameter on COMPLEX is the kind of each of its components. template -struct Type +class Type : public TypeBase { +public: using Part = Type; using Scalar = value::Complex; }; template<> -struct Type +class Type : public TypeBase { +public: using Scalar = std::string; }; template<> -struct Type +class Type : public TypeBase { +public: using Scalar = std::u16string; }; template<> -struct Type +class Type : public TypeBase { +public: using Scalar = std::u32string; }; template -struct Type +class Type : public TypeBase { +public: using Scalar = value::Logical<8 * KIND>; }; +template<> class Type { +public: + static constexpr bool isSpecificType{true}; + static constexpr TypeCategory category{TypeCategory::Derived}; + using Scalar = void; + + CLASS_BOILERPLATE(Type) + explicit Type(const semantics::DerivedTypeSpec &s) : spec_{&s} {} + + const semantics::DerivedTypeSpec &spec() const { return *spec_; } + std::string Dump() const; + +private: + // This member should be a reference, except that copy construction + // and assignment would not be possible. + const semantics::DerivedTypeSpec *spec_; +}; + // Type functions template using Scalar = typename std::decay_t::Scalar; diff --git a/flang/lib/evaluate/variable.cc b/flang/lib/evaluate/variable.cc index ccd51e8..81cf416 100644 --- a/flang/lib/evaluate/variable.cc +++ b/flang/lib/evaluate/variable.cc @@ -107,7 +107,7 @@ Expr Substring::first() const { if (first_.has_value()) { return **first_; } - return {1}; + return AsExpr(Constant{1}); } Expr Substring::last() const { @@ -349,8 +349,9 @@ Expr DataRef::LEN() const { u_); } Expr Substring::LEN() const { - return Extremum{AsExpr(Constant{0}), - last() - first() + AsExpr(Constant{1})}; + return AsExpr( + Extremum{AsExpr(Constant{0}), + last() - first() + AsExpr(Constant{1})}); } Expr ProcedureDesignator::LEN() const { return std::visit( diff --git a/flang/lib/semantics/expression.cc b/flang/lib/semantics/expression.cc index b0800a3..adbb24b 100644 --- a/flang/lib/semantics/expression.cc +++ b/flang/lib/semantics/expression.cc @@ -595,6 +595,7 @@ MaybeExpr ExprAnalyzer::Analyze(const parser::Expr::Parentheses &x) { [&](BOZLiteralConstant &&boz) { return operand; // ignore parentheses around typeless }, + [&](Expr> &&dte) { return operand; }, [](auto &&catExpr) { return std::visit( [](auto &&expr) -> MaybeExpr { @@ -635,7 +636,7 @@ MaybeExpr ExprAnalyzer::Analyze(const parser::Expr::UnaryPlus &x) { MaybeExpr ExprAnalyzer::Analyze(const parser::Expr::Negate &x) { if (MaybeExpr operand{AnalyzeHelper(*this, *x.v)}) { - return Negation(context.messages, std::move(operand->u)); + return Negation(context.messages, std::move(*operand)); } return std::nullopt; } -- 2.7.4