diff --git a/flang/lib/evaluate/variable.cc b/flang/lib/evaluate/variable.cc index b0dfc4d3b7cc..3b68e130baef 100644 --- a/flang/lib/evaluate/variable.cc +++ b/flang/lib/evaluate/variable.cc @@ -21,20 +21,101 @@ namespace Fortran::evaluate { +// Constructors, accessors, mutators + Triplet::Triplet(std::optional &&l, std::optional &&u, std::optional &&s) { if (l.has_value()) { - lower = IndirectSubscriptIntegerExpr::Make(std::move(*l)); + lower_ = IndirectSubscriptIntegerExpr::Make(std::move(*l)); } if (u.has_value()) { - upper = IndirectSubscriptIntegerExpr::Make(std::move(*u)); + upper_ = IndirectSubscriptIntegerExpr::Make(std::move(*u)); } if (s.has_value()) { - stride = IndirectSubscriptIntegerExpr::Make(std::move(*s)); + stride_ = IndirectSubscriptIntegerExpr::Make(std::move(*s)); } } +std::optional Triplet::lower() const { + if (lower_) { + return {**lower_}; + } + return {}; +} + +std::optional Triplet::upper() const { + if (upper_) { + return {**upper_}; + } + return {}; +} + +std::optional Triplet::stride() const { + if (stride_) { + return {**stride_}; + } + return {}; +} + +CoarrayRef::CoarrayRef(std::vector &&c, + std::vector &&ss, + std::vector &&css) + : base_(std::move(c)), subscript_(std::move(ss)), cosubscript_(std::move(css)) { + CHECK(!base_.empty()); +} + +CoarrayRef &CoarrayRef::setStat(Variable &&v) { + stat_ = CopyableIndirection::Make(std::move(v)); + return *this; +} + +CoarrayRef &CoarrayRef::setTeam(Variable &&v, bool isTeamNumber) { + team_ = CopyableIndirection::Make(std::move(v)); + teamIsTeamNumber_ = isTeamNumber; + return *this; +} + +Substring::Substring(DataRef &&d, std::optional &&f, + std::optional &&l) + : u{std::move(d)} { + if (f.has_value()) { + first = IndirectSubscriptIntegerExpr::Make(std::move(*f)); + } + if (l.has_value()) { + last = IndirectSubscriptIntegerExpr::Make(std::move(*l)); + } +} + +Substring::Substring(std::string &&s, std::optional &&f, + std::optional &&l) + : u{std::move(s)} { + if (f.has_value()) { + first = IndirectSubscriptIntegerExpr::Make(std::move(*f)); + } + if (l.has_value()) { + last = IndirectSubscriptIntegerExpr::Make(std::move(*l)); + } +} + +SubscriptIntegerExpr Substring::First() const { + if (first.has_value()) { + return **first; + } + return {1}; +} + +SubscriptIntegerExpr Substring::Last() const { + if (last.has_value()) { + return **last; + } + return std::visit(common::visitors{[](const std::string &s) { + return SubscriptIntegerExpr{s.size()}; + }, + [](const DataRef &x) { return x.LEN(); }}, + u); +} + // Variable dumping template std::ostream &Emit(std::ostream &o, const A &x) { @@ -98,20 +179,20 @@ std::ostream &Component::Dump(std::ostream &o) const { } std::ostream &Triplet::Dump(std::ostream &o) const { - Emit(o, lower) << ':'; - Emit(o, upper); - if (stride) { - Emit(o << ':', stride); + Emit(o, lower_) << ':'; + Emit(o, upper_); + if (stride_) { + Emit(o << ':', stride_); } return o; } -std::ostream &Subscript::Dump(std::ostream &o) const { return Emit(o, u); } +std::ostream &Subscript::Dump(std::ostream &o) const { return Emit(o, u_); } std::ostream &ArrayRef::Dump(std::ostream &o) const { - Emit(o, u); + Emit(o, u_); char separator{'('}; - for (const Subscript &ss : subscript) { + for (const Subscript &ss : subscript_) { ss.Dump(o << separator); separator = ','; } @@ -119,11 +200,11 @@ std::ostream &ArrayRef::Dump(std::ostream &o) const { } std::ostream &CoarrayRef::Dump(std::ostream &o) const { - for (const Symbol *sym : base) { + for (const Symbol *sym : base_) { Emit(o, *sym); } char separator{'('}; - for (const auto &ss : subscript) { + for (const auto &ss : subscript_) { Emit(o << separator, ss); separator = ','; } @@ -131,16 +212,16 @@ std::ostream &CoarrayRef::Dump(std::ostream &o) const { o << ')'; } separator = '['; - for (const auto &css : cosubscript) { + for (const auto &css : cosubscript_) { Emit(o << separator, css); separator = ','; } - if (stat.has_value()) { - Emit(o << separator, stat, "STAT="); + if (stat_.has_value()) { + Emit(o << separator, stat_, "STAT="); separator = ','; } - if (team.has_value()) { - Emit(o << separator, team, teamIsTeamNumber ? "TEAM_NUMBER=" : "TEAM="); + if (team_.has_value()) { + Emit(o << separator, team_, teamIsTeamNumber_ ? "TEAM_NUMBER=" : "TEAM="); } return o << ']'; } @@ -190,53 +271,6 @@ std::ostream &Label::Dump(std::ostream &o) const { return o << '*' << std::dec << label; } -CoarrayRef::CoarrayRef(std::vector &&c, - std::vector &&ss, - std::vector &&css) - : base(std::move(c)), subscript(std::move(ss)), cosubscript(std::move(css)) { - CHECK(!base.empty()); -} - -Substring::Substring(DataRef &&d, std::optional &&f, - std::optional &&l) - : u{std::move(d)} { - if (f.has_value()) { - first = IndirectSubscriptIntegerExpr::Make(std::move(*f)); - } - if (l.has_value()) { - last = IndirectSubscriptIntegerExpr::Make(std::move(*l)); - } -} - -Substring::Substring(std::string &&s, std::optional &&f, - std::optional &&l) - : u{std::move(s)} { - if (f.has_value()) { - first = IndirectSubscriptIntegerExpr::Make(std::move(*f)); - } - if (l.has_value()) { - last = IndirectSubscriptIntegerExpr::Make(std::move(*l)); - } -} - -SubscriptIntegerExpr Substring::First() const { - if (first.has_value()) { - return **first; - } - return {1}; -} - -SubscriptIntegerExpr Substring::Last() const { - if (last.has_value()) { - return **last; - } - return std::visit(common::visitors{[](const std::string &s) { - return SubscriptIntegerExpr{s.size()}; - }, - [](const DataRef &x) { return x.LEN(); }}, - u); -} - // LEN() static SubscriptIntegerExpr SymbolLEN(const Symbol &sym) { return SubscriptIntegerExpr{0}; // TODO @@ -246,9 +280,9 @@ SubscriptIntegerExpr ArrayRef::LEN() const { return std::visit( common::visitors{[](const Symbol *s) { return SymbolLEN(*s); }, [](const Component &x) { return x.LEN(); }}, - u); + u_); } -SubscriptIntegerExpr CoarrayRef::LEN() const { return SymbolLEN(*base.back()); } +SubscriptIntegerExpr CoarrayRef::LEN() const { return SymbolLEN(*base_.back()); } SubscriptIntegerExpr DataRef::LEN() const { return std::visit( common::visitors{[](const Symbol *s) { return SymbolLEN(*s); }, diff --git a/flang/lib/evaluate/variable.h b/flang/lib/evaluate/variable.h index e67ab2c2f92b..e18b2c1eeb30 100644 --- a/flang/lib/evaluate/variable.h +++ b/flang/lib/evaluate/variable.h @@ -66,27 +66,32 @@ private: const Symbol *symbol_; }; -// TODO pmk continue data hiding from here... - // R921 subscript-triplet -struct Triplet { +class Triplet { +public: CLASS_BOILERPLATE(Triplet) Triplet(std::optional &&, std::optional &&, std::optional &&); - std::optional lower, upper, stride; + std::optional lower() const; + std::optional upper() const; + std::optional stride() const; +private: + std::optional lower_, upper_, stride_; }; // R919 subscript when rank 0, R923 vector-subscript when rank 1 -struct Subscript { +class Subscript { +public: CLASS_BOILERPLATE(Subscript) explicit Subscript(const SubscriptIntegerExpr &s) - : u{IndirectSubscriptIntegerExpr::Make(s)} {} + : u_{IndirectSubscriptIntegerExpr::Make(s)} {} explicit Subscript(SubscriptIntegerExpr &&s) - : u{IndirectSubscriptIntegerExpr::Make(std::move(s))} {} - explicit Subscript(const Triplet &t) : u{t} {} - explicit Subscript(Triplet &&t) : u{std::move(t)} {} - std::variant u; + : u_{IndirectSubscriptIntegerExpr::Make(std::move(s))} {} + explicit Subscript(const Triplet &t) : u_{t} {} + explicit Subscript(Triplet &&t) : u_{std::move(t)} {} +private: + std::variant u_; }; // R917 array-element, R918 array-section; however, the case of an @@ -94,15 +99,17 @@ struct Subscript { // as a ComplexPart instead. C919 & C925 require that at most one set of // subscripts have rank greater than 0, but that is not explicit in // these types. -struct ArrayRef { +class ArrayRef { +public: CLASS_BOILERPLATE(ArrayRef) ArrayRef(const Symbol &n, std::vector &&ss) - : u{&n}, subscript(std::move(ss)) {} + : u_{&n}, subscript_(std::move(ss)) {} ArrayRef(Component &&c, std::vector &&ss) - : u{std::move(c)}, subscript(std::move(ss)) {} + : u_{std::move(c)}, subscript_(std::move(ss)) {} SubscriptIntegerExpr LEN() const; - std::variant u; - std::vector subscript; +private: + std::variant u_; + std::vector subscript_; }; // R914 coindexed-named-object @@ -112,18 +119,24 @@ struct ArrayRef { // function results. They can be components of other derived types. // C930 precludes having both TEAM= and TEAM_NUMBER=. // TODO C931 prohibits the use of a coindexed object as a stat-variable. -struct CoarrayRef { +class CoarrayRef { +public: CLASS_BOILERPLATE(CoarrayRef) CoarrayRef(std::vector &&, std::vector &&, std::vector &&); // TODO: stat & team? + CoarrayRef &setStat(Variable &&); + CoarrayRef &setTeam(Variable &&, bool isTeamNumber = false); SubscriptIntegerExpr LEN() const; - std::vector base; - std::vector subscript, cosubscript; - std::optional> stat, team; - bool teamIsTeamNumber{false}; // false: TEAM=, true: TEAM_NUMBER= +private: + std::vector base_; + std::vector subscript_, cosubscript_; + std::optional> stat_, team_; + bool teamIsTeamNumber_{false}; // false: TEAM=, true: TEAM_NUMBER= }; +// TODO pmk continue with data hiding from here + // R911 data-ref is defined syntactically as a series of part-refs, which // would be far too expressive if the constraints were ignored. Here, the // possible outcomes are spelled out. Note that a data-ref cannot include