diff --git a/flang/lib/common/idioms.h b/flang/lib/common/idioms.h index 340cb158074e..3004c5817a70 100644 --- a/flang/lib/common/idioms.h +++ b/flang/lib/common/idioms.h @@ -85,7 +85,7 @@ template visitors(LAMBDAS... x)->visitors; // Invoke CLASS_TRAIT(traitName) to define a trait, then put // using traitName = std::true_type; (or false_type) // into the appropriate class definitions. You can then use -// typename std::enable_if, ...>::type +// typename std::enable_if_t, ...> // in template specialization definitions. #define CLASS_TRAIT(T) \ namespace class_trait_ns_##T { \ @@ -94,14 +94,12 @@ template visitors(LAMBDAS... x)->visitors; template \ constexpr bool has_trait{decltype(test(nullptr))::value}; \ template \ - constexpr typename std::enable_if, bool>::type \ - trait_value() { \ + constexpr typename std::enable_if_t, bool> trait_value() { \ using U = typename A::T; \ return U::value; \ } \ template \ - constexpr typename std::enable_if, bool>::type \ - trait_value() { \ + constexpr typename std::enable_if_t, bool> trait_value() { \ return false; \ } \ } \ diff --git a/flang/lib/evaluate/CMakeLists.txt b/flang/lib/evaluate/CMakeLists.txt index af481fbd945e..cf4336602fac 100644 --- a/flang/lib/evaluate/CMakeLists.txt +++ b/flang/lib/evaluate/CMakeLists.txt @@ -18,7 +18,6 @@ add_library(FortranEvaluate integer.cc logical.cc real.cc - type.cc ) target_link_libraries(FortranEvaluate diff --git a/flang/lib/evaluate/common.h b/flang/lib/evaluate/common.h index 74a4ef41576c..dc05f46cd03c 100644 --- a/flang/lib/evaluate/common.h +++ b/flang/lib/evaluate/common.h @@ -16,13 +16,14 @@ #define FORTRAN_EVALUATE_COMMON_H_ #include "../common/enum-set.h" +#include "../common/idioms.h" #include namespace Fortran::evaluate { // Integers are always ordered; reals may not be. -enum class Ordering { Less, Equal, Greater }; -enum class Relation { Less, Equal, Greater, Unordered }; +ENUM_CLASS(Ordering, Less, Equal, Greater) +ENUM_CLASS(Relation, Less, Equal, Greater, Unordered) static constexpr Ordering CompareUnsigned(std::uint64_t x, std::uint64_t y) { if (x < y) { @@ -64,13 +65,8 @@ static constexpr Relation Reverse(Relation relation) { } } -enum class RealFlag { - Overflow, - DivideByZero, - InvalidArgument, - Underflow, - Inexact -}; +ENUM_CLASS( + RealFlag, Overflow, DivideByZero, InvalidArgument, Underflow, Inexact) using RealFlags = common::EnumSet; @@ -83,7 +79,7 @@ template struct ValueWithRealFlags { RealFlags flags; }; -enum class Rounding { TiesToEven, ToZero, Down, Up, TiesAwayFromZero }; +ENUM_CLASS(Rounding, TiesToEven, ToZero, Down, Up, TiesAwayFromZero) #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ constexpr bool IsHostLittleEndian{false}; diff --git a/flang/lib/evaluate/expression.h b/flang/lib/evaluate/expression.h index 7bcda0fdb309..9af5359b30f8 100644 --- a/flang/lib/evaluate/expression.h +++ b/flang/lib/evaluate/expression.h @@ -16,10 +16,13 @@ #define FORTRAN_EVALUATE_EXPRESSION_H_ // Represent Fortran expressions in a type-safe manner. -// Expressions are the sole owners of their constituents; there is no +// Expressions are the sole owners of their constituents; i.e., there is no // context-independent hash table or sharing of common subexpressions. -// Both deep copy and move semantics are supported for expression construction. +// Both deep copy and move semantics are supported for expression construction +// and manipulation in place. // TODO: variable and function references +// TODO: elevate some intrinsics to operations +// TODO: convenience wrappers for constructing conversions #include "common.h" #include "type.h" @@ -41,7 +44,7 @@ struct AnyCharacterExpr; struct AnyIntegerOrRealExpr; // Helper base classes to manage subexpressions, which are known as data members -// named 'x' and (for binary operations) 'y'. +// named 'x' and, for binary operations, 'y'. template struct Unary { Unary(const A &a) : x{std::make_unique(a)} {} Unary(std::unique_ptr &&a) : x{std::move(a)} {} @@ -488,6 +491,9 @@ struct AnyIntegerOrRealExpr { }; // Convenience functions and operator overloadings for expression construction. +// These definitions are created with temporary helper macros to reduce +// C++ boilerplate. All combinations of lvalue and rvalue references are +// allowed for operands. #define UNARY(FUNC, CONSTR) \ template A FUNC(const A &x) { return {typename A::CONSTR{x}}; } UNARY(Parentheses, Parentheses) diff --git a/flang/lib/evaluate/type.cc b/flang/lib/evaluate/type.cc deleted file mode 100644 index 3f010efa1117..000000000000 --- a/flang/lib/evaluate/type.cc +++ /dev/null @@ -1,31 +0,0 @@ -// 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 - -namespace Fortran::evaluate { - -std::string CategoryName(Category c) { - switch (c) { - case Category::Integer: return "Integer"; - case Category::Real: return "Real"; - case Category::Complex: return "Complex"; - case Category::Logical: return "Logical"; - case Category::Character: return "Character"; - case Category::Derived: return "Derived"; - } - return ""; // placate g++ -} -} // namespace Fortran::evaluate diff --git a/flang/lib/evaluate/type.h b/flang/lib/evaluate/type.h index bf9edc7d1a2a..3ef5ee582e55 100644 --- a/flang/lib/evaluate/type.h +++ b/flang/lib/evaluate/type.h @@ -24,21 +24,20 @@ #include "integer.h" #include "logical.h" #include "real.h" +#include "../common/idioms.h" #include #include namespace Fortran::evaluate { -enum class Category { Integer, Real, Complex, Logical, Character, Derived }; - -std::string CategoryName(Category); +ENUM_CLASS(Category, Integer, Real, Complex, Logical, Character, Derived) template struct TypeBase { static constexpr Category category{C}; static constexpr int kind{KIND}; static constexpr bool hasLen{false}; static std::string Dump() { - return CategoryName(category) + '(' + std::to_string(kind) + ')'; + return EnumToString(category) + '(' + std::to_string(kind) + ')'; } }; diff --git a/flang/lib/parser/basic-parsers.h b/flang/lib/parser/basic-parsers.h index 3a9a260f6f94..822efb1bb80d 100644 --- a/flang/lib/parser/basic-parsers.h +++ b/flang/lib/parser/basic-parsers.h @@ -969,18 +969,16 @@ private: // With a single argument that is a parser with a usable value of // type A, construct(p) invokes T's explicit constructor T(A &&). template -constexpr - typename std::enable_if, - Construct01>::type - construct(const PA &parser) { +constexpr std::enable_if_t, + Construct01> +construct(const PA &parser) { return Construct01{parser}; } template -constexpr - typename std::enable_if, - Construct1>::type - construct(const PA &parser) { +constexpr std::enable_if_t, + Construct1> +construct(const PA &parser) { return Construct1{parser}; } diff --git a/flang/lib/parser/parse-tree-visitor.h b/flang/lib/parser/parse-tree-visitor.h index 39442f804f8d..c481379d5dc6 100644 --- a/flang/lib/parser/parse-tree-visitor.h +++ b/flang/lib/parser/parse-tree-visitor.h @@ -35,17 +35,15 @@ namespace Fortran::parser { // Default case for visitation of non-class data members and strings template -typename std::enable_if || - std::is_same_v>::type -Walk(const A &x, V &visitor) { +std::enable_if_t || std::is_same_v> Walk( + const A &x, V &visitor) { if (visitor.Pre(x)) { visitor.Post(x); } } template -typename std::enable_if || - std::is_same_v>::type -Walk(A &x, M &mutator) { +std::enable_if_t || std::is_same_v> Walk( + A &x, M &mutator) { if (mutator.Pre(x)) { mutator.Post(x); } @@ -142,27 +140,27 @@ void Walk(std::pair &x, M &mutator) { // Trait-determined traversal of empty, tuple, union, and wrapper classes. template -typename std::enable_if>::type Walk(const A &x, V &visitor) { +std::enable_if_t> Walk(const A &x, V &visitor) { if (visitor.Pre(x)) { visitor.Post(x); } } template -typename std::enable_if>::type Walk(A &x, M &mutator) { +std::enable_if_t> Walk(A &x, M &mutator) { if (mutator.Pre(x)) { mutator.Post(x); } } template -typename std::enable_if>::type Walk(const A &x, V &visitor) { +std::enable_if_t> Walk(const A &x, V &visitor) { if (visitor.Pre(x)) { Walk(x.t, visitor); visitor.Post(x); } } template -typename std::enable_if>::type Walk(A &x, M &mutator) { +std::enable_if_t> Walk(A &x, M &mutator) { if (mutator.Pre(x)) { Walk(x.t, mutator); mutator.Post(x); @@ -170,14 +168,14 @@ typename std::enable_if>::type Walk(A &x, M &mutator) { } template -typename std::enable_if>::type Walk(const A &x, V &visitor) { +std::enable_if_t> Walk(const A &x, V &visitor) { if (visitor.Pre(x)) { Walk(x.u, visitor); visitor.Post(x); } } template -typename std::enable_if>::type Walk(A &x, M &mutator) { +std::enable_if_t> Walk(A &x, M &mutator) { if (mutator.Pre(x)) { Walk(x.u, mutator); mutator.Post(x); @@ -185,14 +183,14 @@ typename std::enable_if>::type Walk(A &x, M &mutator) { } template -typename std::enable_if>::type Walk(const A &x, V &visitor) { +std::enable_if_t> Walk(const A &x, V &visitor) { if (visitor.Pre(x)) { Walk(x.v, visitor); visitor.Post(x); } } template -typename std::enable_if>::type Walk(A &x, M &mutator) { +std::enable_if_t> Walk(A &x, M &mutator) { if (mutator.Pre(x)) { Walk(x.v, mutator); mutator.Post(x);