forked from OSchip/llvm-project
[flang] checkpoint once everything builds again
Original-commit: flang-compiler/f18@2075b88772 Reviewed-on: https://github.com/flang-compiler/f18/pull/144 Tree-same-pre-rewrite: false
This commit is contained in:
parent
6c4773012c
commit
f24cd7dd2d
|
@ -61,15 +61,17 @@ std::ostream &Unary<A>::Dump(std::ostream &o, const char *opr) const {
|
|||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
std::ostream &Binary<A, B>::Dump(std::ostream &o, const char *opr) const {
|
||||
return y->Dump(x->Dump(o << '(') << opr) << ')';
|
||||
std::ostream &Binary<A, B>::Dump(
|
||||
std::ostream &o, const char *opr, const char *before) const {
|
||||
return y->Dump(x->Dump(o << before) << opr) << ')';
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
std::ostream &Expr<Category::Integer, KIND>::Dump(std::ostream &o) const {
|
||||
std::visit(
|
||||
common::visitors{[&](const Constant &n) { o << n.SignedDecimal(); },
|
||||
[&](const CopyableIndirection<Designator> &d) { d->Dump(o); },
|
||||
[&](const CopyableIndirection<DataRef> &d) { d->Dump(o); },
|
||||
[&](const CopyableIndirection<FunctionRef> &d) { d->Dump(o); },
|
||||
[&](const Parentheses &p) { p.Dump(o, "("); },
|
||||
[&](const Negate &n) { n.Dump(o, "(-"); },
|
||||
[&](const Add &a) { a.Dump(o, "+"); },
|
||||
|
@ -77,6 +79,8 @@ std::ostream &Expr<Category::Integer, KIND>::Dump(std::ostream &o) const {
|
|||
[&](const Multiply &m) { m.Dump(o, "*"); },
|
||||
[&](const Divide &d) { d.Dump(o, "/"); },
|
||||
[&](const Power &p) { p.Dump(o, "**"); },
|
||||
[&](const Max &m) { m.Dump(o, ",", "MAX("); },
|
||||
[&](const Min &m) { m.Dump(o, ",", "MIN("); },
|
||||
[&](const auto &convert) { DumpExprWithType(o, convert.x->u); }},
|
||||
u);
|
||||
return o;
|
||||
|
@ -86,6 +90,9 @@ template<int KIND>
|
|||
std::ostream &Expr<Category::Real, KIND>::Dump(std::ostream &o) const {
|
||||
std::visit(
|
||||
common::visitors{[&](const Constant &n) { o << n.DumpHexadecimal(); },
|
||||
[&](const CopyableIndirection<DataRef> &d) { d->Dump(o); },
|
||||
[&](const CopyableIndirection<ComplexPart> &d) { d->Dump(o); },
|
||||
[&](const CopyableIndirection<FunctionRef> &d) { d->Dump(o); },
|
||||
[&](const Parentheses &p) { p.Dump(o, "("); },
|
||||
[&](const Negate &n) { n.Dump(o, "(-"); },
|
||||
[&](const Add &a) { a.Dump(o, "+"); },
|
||||
|
@ -94,6 +101,8 @@ std::ostream &Expr<Category::Real, KIND>::Dump(std::ostream &o) const {
|
|||
[&](const Divide &d) { d.Dump(o, "/"); },
|
||||
[&](const Power &p) { p.Dump(o, "**"); },
|
||||
[&](const IntPower &p) { p.Dump(o, "**"); },
|
||||
[&](const Max &m) { m.Dump(o, ",", "MAX("); },
|
||||
[&](const Min &m) { m.Dump(o, ",", "MIN("); },
|
||||
[&](const RealPart &z) { z.Dump(o, "REAL("); },
|
||||
[&](const AIMAG &p) { p.Dump(o, "AIMAG("); },
|
||||
[&](const auto &convert) { DumpExprWithType(o, convert.x->u); }},
|
||||
|
@ -105,6 +114,8 @@ template<int KIND>
|
|||
std::ostream &Expr<Category::Complex, KIND>::Dump(std::ostream &o) const {
|
||||
std::visit(
|
||||
common::visitors{[&](const Constant &n) { o << n.DumpHexadecimal(); },
|
||||
[&](const CopyableIndirection<DataRef> &d) { d->Dump(o); },
|
||||
[&](const CopyableIndirection<FunctionRef> &d) { d->Dump(o); },
|
||||
[&](const Parentheses &p) { p.Dump(o, "("); },
|
||||
[&](const Negate &n) { n.Dump(o, "(-"); },
|
||||
[&](const Add &a) { a.Dump(o, "+"); },
|
||||
|
@ -123,9 +134,10 @@ std::ostream &Expr<Category::Character, KIND>::Dump(std::ostream &o) const {
|
|||
std::visit(common::visitors{[&](const Constant &s) {
|
||||
o << parser::QuoteCharacterLiteral(s);
|
||||
},
|
||||
[&](const auto &concat) {
|
||||
concat.y->Dump(concat.x->Dump(o) << "//");
|
||||
}},
|
||||
[&](const Concat &concat) { concat.Dump(o, "//"); },
|
||||
[&](const Max &m) { m.Dump(o, ",", "MAX("); },
|
||||
[&](const Min &m) { m.Dump(o, ",", "MIN("); },
|
||||
[&](const auto &ind) { ind->Dump(o); }},
|
||||
u);
|
||||
return o;
|
||||
}
|
||||
|
@ -141,6 +153,8 @@ template<typename A> std::ostream &Comparison<A>::Dump(std::ostream &o) const {
|
|||
std::ostream &Expr<Category::Logical, 1>::Dump(std::ostream &o) const {
|
||||
std::visit(
|
||||
common::visitors{[&](const bool &tf) { o << (tf ? ".T." : ".F."); },
|
||||
[&](const CopyableIndirection<DataRef> &d) { d->Dump(o); },
|
||||
[&](const CopyableIndirection<FunctionRef> &d) { d->Dump(o); },
|
||||
[&](const Not &n) { n.Dump(o, "(.NOT."); },
|
||||
[&](const And &a) { a.Dump(o, ".AND."); },
|
||||
[&](const Or &a) { a.Dump(o, ".OR."); },
|
||||
|
@ -151,6 +165,28 @@ std::ostream &Expr<Category::Logical, 1>::Dump(std::ostream &o) const {
|
|||
return o;
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
SubscriptIntegerExpr Expr<Category::Character, KIND>::LEN() const {
|
||||
return std::visit(
|
||||
common::visitors{
|
||||
[](const Constant &c) { return SubscriptIntegerExpr{c.size()}; },
|
||||
[](const Concat &c) { return c.x->LEN() + c.y->LEN(); },
|
||||
[](const Max &c) {
|
||||
return SubscriptIntegerExpr{
|
||||
SubscriptIntegerExpr::Max{c.x->LEN(), c.y->LEN()}};
|
||||
},
|
||||
[](const Min &c) {
|
||||
return SubscriptIntegerExpr{
|
||||
SubscriptIntegerExpr::Max{c.x->LEN(), c.y->LEN()}};
|
||||
},
|
||||
[](const CopyableIndirection<DataRef> &dr) { return dr->LEN(); },
|
||||
[](const CopyableIndirection<Substring> &ss) { return ss->LEN(); },
|
||||
[](const CopyableIndirection<FunctionRef> &fr) {
|
||||
return fr->proc.LEN();
|
||||
}},
|
||||
u);
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
void Expr<Category::Integer, KIND>::Fold(FoldingContext &context) {
|
||||
std::visit(common::visitors{[&](Parentheses &p) {
|
||||
|
@ -208,24 +244,6 @@ void Expr<Category::Integer, KIND>::Fold(FoldingContext &context) {
|
|||
u);
|
||||
}
|
||||
|
||||
template<int KIND>
|
||||
typename CharacterExpr<KIND>::LengthExpr CharacterExpr<KIND>::LEN() const {
|
||||
// Written thus, instead of with common::visitors{}, to dodge a
|
||||
// bug in g++ 7.2.0 that failed to direct the std::string case to its
|
||||
// specific alternative.
|
||||
return std::visit(
|
||||
[](const auto &x) {
|
||||
if constexpr (std::is_same_v<
|
||||
const typename CharacterExpr<KIND>::Constant &,
|
||||
decltype(x)>) {
|
||||
return LengthExpr{static_cast<std::uint64_t>(x.size())};
|
||||
} else {
|
||||
return LengthExpr{LengthExpr::Add{x.x->LEN(), x.y->LEN()}};
|
||||
}
|
||||
},
|
||||
u);
|
||||
}
|
||||
|
||||
template struct Expr<Category::Integer, 1>;
|
||||
template struct Expr<Category::Integer, 2>;
|
||||
template struct Expr<Category::Integer, 4>;
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
// context-independent hash table or sharing of common subexpressions.
|
||||
// Both deep copy and move semantics are supported for expression construction
|
||||
// and manipulation in place.
|
||||
// TODO: elevate some intrinsics to operations
|
||||
// TODO: convenience wrappers for constructing conversions
|
||||
|
||||
#include "common.h"
|
||||
|
@ -57,7 +56,8 @@ template<typename A, typename B = A> struct Binary {
|
|||
Binary(CopyableIndirection<const A> &&a, CopyableIndirection<const B> &&b)
|
||||
: x{std::move(a)}, y{std::move(b)} {}
|
||||
Binary(A &&a, B &&b) : x{std::move(a)}, y{std::move(b)} {}
|
||||
std::ostream &Dump(std::ostream &, const char *opr) const;
|
||||
std::ostream &Dump(
|
||||
std::ostream &, const char *opr, const char *before = "(") const;
|
||||
CopyableIndirection<A> x;
|
||||
CopyableIndirection<B> y;
|
||||
};
|
||||
|
@ -91,6 +91,12 @@ template<int KIND> struct Expr<Category::Integer, KIND> {
|
|||
struct Power : public Bin {
|
||||
using Bin::Bin;
|
||||
};
|
||||
struct Max : public Bin {
|
||||
using Bin::Bin;
|
||||
};
|
||||
struct Min : public Bin {
|
||||
using Bin::Bin;
|
||||
};
|
||||
// TODO: R916 type-param-inquiry
|
||||
|
||||
CLASS_BOILERPLATE(Expr)
|
||||
|
@ -110,13 +116,14 @@ template<int KIND> struct Expr<Category::Integer, KIND> {
|
|||
(std::is_base_of_v<Un, A> || std::is_base_of_v<Bin, A>),
|
||||
A> &&x)
|
||||
: u(std::move(x)) {}
|
||||
template<typename A> Expr(CopyableIndirection<A> &&x) : u{std::move(x)} {}
|
||||
|
||||
void Fold(FoldingContext &);
|
||||
|
||||
// TODO: function reference
|
||||
std::variant<Constant, CopyableIndirection<Designator>,
|
||||
Convert<GenericIntegerExpr>, Convert<GenericRealExpr>, Parentheses,
|
||||
Negate, Add, Subtract, Multiply, Divide, Power>
|
||||
std::variant<Constant, CopyableIndirection<DataRef>,
|
||||
CopyableIndirection<FunctionRef>, Convert<GenericIntegerExpr>,
|
||||
Convert<GenericRealExpr>, Parentheses, Negate, Add, Subtract, Multiply,
|
||||
Divide, Power, Max, Min>
|
||||
u;
|
||||
};
|
||||
|
||||
|
@ -155,6 +162,12 @@ template<int KIND> struct Expr<Category::Real, KIND> {
|
|||
struct IntPower : public Binary<Expr, GenericIntegerExpr> {
|
||||
using Binary<Expr, GenericIntegerExpr>::Binary;
|
||||
};
|
||||
struct Max : public Bin {
|
||||
using Bin::Bin;
|
||||
};
|
||||
struct Min : public Bin {
|
||||
using Bin::Bin;
|
||||
};
|
||||
using CplxUn = Unary<ComplexExpr<KIND>>;
|
||||
struct RealPart : public CplxUn {
|
||||
using CplxUn::CplxUn;
|
||||
|
@ -174,10 +187,12 @@ template<int KIND> struct Expr<Category::Real, KIND> {
|
|||
template<typename A> Expr(const A &x) : u{x} {}
|
||||
template<typename A>
|
||||
Expr(std::enable_if_t<!std::is_reference_v<A>, A> &&x) : u{std::move(x)} {}
|
||||
template<typename A> Expr(CopyableIndirection<A> &&x) : u{std::move(x)} {}
|
||||
|
||||
// TODO: designators, function references
|
||||
std::variant<Constant, Convert<GenericIntegerExpr>, Convert<GenericRealExpr>,
|
||||
Parentheses, Negate, Add, Subtract, Multiply, Divide, Power, IntPower,
|
||||
std::variant<Constant, CopyableIndirection<DataRef>,
|
||||
CopyableIndirection<ComplexPart>, CopyableIndirection<FunctionRef>,
|
||||
Convert<GenericIntegerExpr>, Convert<GenericRealExpr>, Parentheses,
|
||||
Negate, Add, Subtract, Multiply, Divide, Power, IntPower, Max, Min,
|
||||
RealPart, AIMAG>
|
||||
u;
|
||||
};
|
||||
|
@ -220,28 +235,42 @@ template<int KIND> struct Expr<Category::Complex, KIND> {
|
|||
template<typename A> Expr(const A &x) : u{x} {}
|
||||
template<typename A>
|
||||
Expr(std::enable_if_t<!std::is_reference_v<A>, A> &&x) : u{std::move(x)} {}
|
||||
template<typename A> Expr(CopyableIndirection<A> &&x) : u{std::move(x)} {}
|
||||
|
||||
// TODO: designators, function references
|
||||
std::variant<Constant, Parentheses, Negate, Add, Subtract, Multiply, Divide,
|
||||
Power, IntPower, CMPLX>
|
||||
std::variant<Constant, CopyableIndirection<DataRef>,
|
||||
CopyableIndirection<FunctionRef>, Parentheses, Negate, Add, Subtract,
|
||||
Multiply, Divide, Power, IntPower, CMPLX>
|
||||
u;
|
||||
};
|
||||
|
||||
template<int KIND> struct Expr<Category::Character, KIND> {
|
||||
using Result = Type<Category::Character, KIND>;
|
||||
using Constant = typename Result::Value;
|
||||
using LengthExpr = IntegerExpr<IntrinsicTypeParameterType::kind>;
|
||||
using Bin = Binary<Expr>;
|
||||
struct Concat : public Bin {
|
||||
using Bin::Bin;
|
||||
};
|
||||
struct Max : public Bin {
|
||||
using Bin::Bin;
|
||||
};
|
||||
struct Min : public Bin {
|
||||
using Bin::Bin;
|
||||
};
|
||||
|
||||
CLASS_BOILERPLATE(Expr)
|
||||
Expr(const Constant &x) : u{x} {}
|
||||
Expr(Constant &&x) : u{std::move(x)} {}
|
||||
Expr(const Expr &x, const Expr &y) : u{Binary<Expr>{x, y}} {}
|
||||
Expr(Expr &&x, Expr &&y) : u{Binary<Expr>{std::move(x), std::move(y)}} {}
|
||||
template<typename A> Expr(const A &x) : u{x} {}
|
||||
template<typename A>
|
||||
Expr(std::enable_if_t<!std::is_reference_v<A>, A> &&x) : u{std::move(x)} {}
|
||||
template<typename A> Expr(CopyableIndirection<A> &&x) : u{std::move(x)} {}
|
||||
|
||||
LengthExpr LEN() const;
|
||||
SubscriptIntegerExpr LEN() const;
|
||||
|
||||
// TODO: designators, function references
|
||||
std::variant<Constant, Binary<Expr>> u;
|
||||
std::variant<Constant, CopyableIndirection<DataRef>,
|
||||
CopyableIndirection<Substring>, CopyableIndirection<FunctionRef>, Concat,
|
||||
Max, Min>
|
||||
u;
|
||||
};
|
||||
|
||||
// The Comparison class template is a helper for constructing logical
|
||||
|
@ -317,9 +346,10 @@ template<> struct Expr<Category::Logical, 1> {
|
|||
template<typename A> Expr(const A &x) : u(x) {}
|
||||
template<typename A>
|
||||
Expr(std::enable_if_t<!std::is_reference_v<A>, A> &&x) : u{std::move(x)} {}
|
||||
template<typename A> Expr(CopyableIndirection<A> &&x) : u{std::move(x)} {}
|
||||
|
||||
// TODO: designators, function references
|
||||
std::variant<Constant, Not, And, Or, Eqv, Neqv,
|
||||
std::variant<Constant, CopyableIndirection<DataRef>,
|
||||
CopyableIndirection<FunctionRef>, Not, And, Or, Eqv, Neqv,
|
||||
CategoryComparison<Category::Integer>, CategoryComparison<Category::Real>,
|
||||
CategoryComparison<Category::Complex>,
|
||||
CategoryComparison<Category::Character>>
|
||||
|
|
|
@ -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.
|
||||
|
||||
#ifndef FORTRAN_EVALUATE_INTRINSICS_H_
|
||||
#define FORTRAN_EVALUATE_INTRINSICS_H_
|
||||
|
||||
#include "../common/idioms.h"
|
||||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
ENUM_CLASS(IntrinsicProcedure, LEN, MAX, MIN)
|
||||
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_INTRINSICS_H_
|
|
@ -25,13 +25,13 @@ Triplet::Triplet(std::optional<SubscriptIntegerExpr> &&l,
|
|||
std::optional<SubscriptIntegerExpr> &&u,
|
||||
std::optional<SubscriptIntegerExpr> &&s) {
|
||||
if (l.has_value()) {
|
||||
lower = SubscriptIntegerExpr{std::move(*l)};
|
||||
lower = IndirectSubscriptIntegerExpr::Make(std::move(*l));
|
||||
}
|
||||
if (u.has_value()) {
|
||||
upper = SubscriptIntegerExpr{std::move(*u)};
|
||||
upper = IndirectSubscriptIntegerExpr::Make(std::move(*u));
|
||||
}
|
||||
if (s.has_value()) {
|
||||
stride = SubscriptIntegerExpr{std::move(*s)};
|
||||
stride = IndirectSubscriptIntegerExpr::Make(std::move(*s));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,10 @@ template<> std::ostream &Emit(std::ostream &o, const Symbol &symbol) {
|
|||
return o << symbol.name().ToString();
|
||||
}
|
||||
|
||||
template<> std::ostream &Emit(std::ostream &o, const IntrinsicProcedure &p) {
|
||||
return o << EnumToString(p);
|
||||
}
|
||||
|
||||
std::ostream &Component::Dump(std::ostream &o) const {
|
||||
base->Dump(o);
|
||||
return Emit(o << '%', sym);
|
||||
|
@ -119,7 +123,7 @@ std::ostream &CoarrayRef::Dump(std::ostream &o) const {
|
|||
Emit(o, *sym);
|
||||
}
|
||||
char separator{'('};
|
||||
for (const SubscriptIntegerExpr &ss : subscript) {
|
||||
for (const auto &ss : subscript) {
|
||||
Emit(o << separator, ss);
|
||||
separator = ',';
|
||||
}
|
||||
|
@ -127,7 +131,7 @@ std::ostream &CoarrayRef::Dump(std::ostream &o) const {
|
|||
o << ')';
|
||||
}
|
||||
separator = '[';
|
||||
for (const SubscriptIntegerExpr &css : cosubscript) {
|
||||
for (const auto &css : cosubscript) {
|
||||
Emit(o << separator, css);
|
||||
separator = ',';
|
||||
}
|
||||
|
@ -185,4 +189,85 @@ std::ostream &ActualSubroutineArg::Dump(std::ostream &o) const {
|
|||
std::ostream &Label::Dump(std::ostream &o) const {
|
||||
return o << '*' << std::dec << label;
|
||||
}
|
||||
|
||||
CoarrayRef::CoarrayRef(std::vector<const Symbol *> &&c,
|
||||
std::vector<SubscriptIntegerExpr> &&ss,
|
||||
std::vector<SubscriptIntegerExpr> &&css)
|
||||
: base(std::move(c)), subscript(std::move(ss)), cosubscript(std::move(css)) {
|
||||
CHECK(!base.empty());
|
||||
}
|
||||
|
||||
Substring::Substring(DataRef &&d, std::optional<SubscriptIntegerExpr> &&f,
|
||||
std::optional<SubscriptIntegerExpr> &&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<SubscriptIntegerExpr> &&f,
|
||||
std::optional<SubscriptIntegerExpr> &&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
|
||||
}
|
||||
SubscriptIntegerExpr Component::LEN() const { return SymbolLEN(sym); }
|
||||
SubscriptIntegerExpr ArrayRef::LEN() const {
|
||||
return std::visit(
|
||||
common::visitors{[](const Symbol *s) { return SymbolLEN(s); },
|
||||
[](const Component &x) { return x.LEN(); }},
|
||||
u);
|
||||
}
|
||||
SubscriptIntegerExpr CoarrayRef::LEN() const { return SymbolLEN(base.back()); }
|
||||
SubscriptIntegerExpr DataRef::LEN() const {
|
||||
return std::visit(
|
||||
common::visitors{[](const Symbol *s) { return SymbolLEN(s); },
|
||||
[](const auto &x) { return x.LEN(); }},
|
||||
u);
|
||||
}
|
||||
SubscriptIntegerExpr Substring::LEN() const {
|
||||
return SubscriptIntegerExpr::Max{
|
||||
SubscriptIntegerExpr{0}, Last() - First() + SubscriptIntegerExpr{1}};
|
||||
}
|
||||
SubscriptIntegerExpr ProcedureDesignator::LEN() const {
|
||||
return std::visit(
|
||||
common::visitors{[](const Symbol *s) { return SymbolLEN(s); },
|
||||
[](const Component &c) { return c.LEN(); },
|
||||
[](const auto &) {
|
||||
CRASH_NO_CASE;
|
||||
return SubscriptIntegerExpr{0};
|
||||
}},
|
||||
u);
|
||||
}
|
||||
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "expression-forward.h"
|
||||
#include "intrinsics.h"
|
||||
#include "../common/idioms.h"
|
||||
#include "../semantics/symbol.h"
|
||||
#include <optional>
|
||||
|
@ -41,8 +42,8 @@ struct ActualFunctionArg;
|
|||
|
||||
// Subscript and cosubscript expressions are of a kind that matches the
|
||||
// address size, at least at the top level.
|
||||
using SubscriptIntegerExpr =
|
||||
CopyableIndirection<IntegerExpr<SubscriptInteger::kind>>;
|
||||
using SubscriptIntegerExpr = IntegerExpr<SubscriptInteger::kind>;
|
||||
using IndirectSubscriptIntegerExpr = CopyableIndirection<SubscriptIntegerExpr>;
|
||||
|
||||
// R913 structure-component & C920: Defined to be a multi-part
|
||||
// data-ref whose last part has no subscripts (or image-selector, although
|
||||
|
@ -54,6 +55,7 @@ struct Component {
|
|||
Component(const DataRef &b, const Symbol &c) : base{b}, sym{&c} {}
|
||||
Component(CopyableIndirection<DataRef> &&b, const Symbol &c)
|
||||
: base{std::move(b)}, sym{&c} {}
|
||||
SubscriptIntegerExpr LEN() const;
|
||||
CopyableIndirection<DataRef> base;
|
||||
const Symbol *sym;
|
||||
};
|
||||
|
@ -64,17 +66,19 @@ struct Triplet {
|
|||
Triplet(std::optional<SubscriptIntegerExpr> &&,
|
||||
std::optional<SubscriptIntegerExpr> &&,
|
||||
std::optional<SubscriptIntegerExpr> &&);
|
||||
std::optional<SubscriptIntegerExpr> lower, upper, stride;
|
||||
std::optional<IndirectSubscriptIntegerExpr> lower, upper, stride;
|
||||
};
|
||||
|
||||
// R919 subscript when rank 0, R923 vector-subscript when rank 1
|
||||
struct Subscript {
|
||||
CLASS_BOILERPLATE(Subscript)
|
||||
explicit Subscript(const SubscriptIntegerExpr &s) : u{s} {}
|
||||
explicit Subscript(SubscriptIntegerExpr &&s) : u{std::move(s)} {}
|
||||
explicit Subscript(const SubscriptIntegerExpr &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<SubscriptIntegerExpr, Triplet> u;
|
||||
std::variant<IndirectSubscriptIntegerExpr, Triplet> u;
|
||||
};
|
||||
|
||||
// R917 array-element, R918 array-section; however, the case of an
|
||||
|
@ -88,6 +92,7 @@ struct ArrayRef {
|
|||
: u{&n}, subscript(std::move(ss)) {}
|
||||
ArrayRef(Component &&c, std::vector<Subscript> &&ss)
|
||||
: u{std::move(c)}, subscript(std::move(ss)) {}
|
||||
SubscriptIntegerExpr LEN() const;
|
||||
std::variant<const Symbol *, Component> u;
|
||||
std::vector<Subscript> subscript;
|
||||
};
|
||||
|
@ -101,11 +106,10 @@ struct ArrayRef {
|
|||
// TODO C931 prohibits the use of a coindexed object as a stat-variable.
|
||||
struct CoarrayRef {
|
||||
CLASS_BOILERPLATE(CoarrayRef)
|
||||
CoarrayRef(std::vector<const Symbol *> &&c,
|
||||
std::vector<SubscriptIntegerExpr> &&ss,
|
||||
std::vector<SubscriptIntegerExpr> &&css)
|
||||
: base(std::move(c)), subscript(std::move(ss)),
|
||||
cosubscript(std::move(css)) {}
|
||||
CoarrayRef(std::vector<const Symbol *> &&,
|
||||
std::vector<SubscriptIntegerExpr> &&,
|
||||
std::vector<SubscriptIntegerExpr> &&); // TODO: stat & team?
|
||||
SubscriptIntegerExpr LEN() const;
|
||||
std::vector<const Symbol *> base;
|
||||
std::vector<SubscriptIntegerExpr> subscript, cosubscript;
|
||||
std::optional<CopyableIndirection<Variable>> stat, team;
|
||||
|
@ -113,16 +117,17 @@ struct CoarrayRef {
|
|||
};
|
||||
|
||||
// R911 data-ref is defined syntactically as a series of part-refs, which
|
||||
// is far too expressive if the constraints are ignored. Here, the possible
|
||||
// outcomes are spelled out. Note that a data-ref cannot include a terminal
|
||||
// substring range or complex component designator; use R901 designator
|
||||
// for that.
|
||||
// would be far too expressive if the constraints were ignored. Here, the
|
||||
// possible outcomes are spelled out. Note that a data-ref cannot include
|
||||
// a terminal substring range or complex component designator; use
|
||||
// R901 designator for that.
|
||||
struct DataRef {
|
||||
CLASS_BOILERPLATE(DataRef)
|
||||
explicit DataRef(const Symbol &n) : u{&n} {}
|
||||
explicit DataRef(Component &&c) : u{std::move(c)} {}
|
||||
explicit DataRef(ArrayRef &&a) : u{std::move(a)} {}
|
||||
explicit DataRef(CoarrayRef &&a) : u{std::move(a)} {}
|
||||
SubscriptIntegerExpr LEN() const;
|
||||
std::variant<const Symbol *, Component, ArrayRef, CoarrayRef> u;
|
||||
};
|
||||
|
||||
|
@ -132,14 +137,17 @@ struct DataRef {
|
|||
// variants of sections instead.
|
||||
struct Substring {
|
||||
CLASS_BOILERPLATE(Substring)
|
||||
Substring(DataRef &&d, std::optional<SubscriptIntegerExpr> &&f,
|
||||
std::optional<SubscriptIntegerExpr> &&l)
|
||||
: u{std::move(d)}, first{std::move(f)}, last{std::move(l)} {}
|
||||
Substring(std::string &&s, std::optional<SubscriptIntegerExpr> &&f,
|
||||
std::optional<SubscriptIntegerExpr> &&l)
|
||||
: u{std::move(s)}, first{std::move(f)}, last{std::move(l)} {}
|
||||
Substring(DataRef &&, std::optional<SubscriptIntegerExpr> &&,
|
||||
std::optional<SubscriptIntegerExpr> &&);
|
||||
Substring(std::string &&, std::optional<SubscriptIntegerExpr> &&,
|
||||
std::optional<SubscriptIntegerExpr> &&);
|
||||
|
||||
SubscriptIntegerExpr First() const;
|
||||
SubscriptIntegerExpr Last() const;
|
||||
SubscriptIntegerExpr LEN() const;
|
||||
|
||||
std::variant<DataRef, std::string> u;
|
||||
std::optional<SubscriptIntegerExpr> first, last;
|
||||
std::optional<IndirectSubscriptIntegerExpr> first, last;
|
||||
};
|
||||
|
||||
// R915 complex-part-designator
|
||||
|
@ -165,10 +173,12 @@ struct Designator {
|
|||
|
||||
struct ProcedureDesignator {
|
||||
CLASS_BOILERPLATE(ProcedureDesignator)
|
||||
explicit ProcedureDesignator(IntrinsicProcedure p) : u{p} {}
|
||||
explicit ProcedureDesignator(const Symbol &n) : u{&n} {}
|
||||
explicit ProcedureDesignator(const Component &c) : u{c} {}
|
||||
explicit ProcedureDesignator(Component &&c) : u{std::move(c)} {}
|
||||
std::variant<const Symbol *, Component> u;
|
||||
SubscriptIntegerExpr LEN() const;
|
||||
std::variant<IntrinsicProcedure, const Symbol *, Component> u;
|
||||
};
|
||||
|
||||
template<typename ARG> struct ProcedureRef {
|
||||
|
|
Loading…
Reference in New Issue