A &value() { return *p_; }
const A &value() const { return *p_; }
- A &operator*() { return *p_; }
- const A &operator*() const { return *p_; }
- A *operator->() { return p_; }
- const A *operator->() const { return p_; }
bool operator==(const A &x) const { return *p_ == x; }
bool operator==(const Indirection &that) const { return *p_ == *that.p_; }
A &value() { return *p_; }
const A &value() const { return *p_; }
- A &operator*() { return *p_; }
- const A &operator*() const { return *p_; }
- A *operator->() { return p_; }
- const A *operator->() const { return p_; }
bool operator==(const A &x) const { return *p_ == x; }
bool operator==(const Indirection &that) const { return *p_ == *that.p_; }
return *this = OwningPointer(std::move(p));
}
- A &operator*() { return *p_; }
- const A &operator*() const { return *p_; }
- A *operator->() { return p_; }
- const A *operator->() const { return p_; }
-
- A *get() const { return p_; }
+ bool has_value() const { return p_ != nullptr; }
+ A &value() {
+ CHECK(p_ != nullptr);
+ return *p_;
+ }
+ const A &value() const {
+ CHECK(p_ != nullptr);
+ return *p_;
+ }
bool operator==(const A &x) const { return p_ != nullptr && *p_ == x; }
bool operator==(const OwningPointer &that) const {
return *this = ForwardReference(std::move(p));
}
- A &operator*() { return *p_; }
- const A &operator*() const { return *p_; }
- A *operator->() { return p_; }
- const A *operator->() const { return p_; }
-
A &value() { return *p_; }
const A &value() const { return *p_; }
namespace Fortran::evaluate {
std::optional<DynamicType> ActualArgument::GetType() const {
- return value->GetType();
+ return value().GetType();
}
-int ActualArgument::Rank() const { return value->Rank(); }
+int ActualArgument::Rank() const { return value().Rank(); }
bool ActualArgument::operator==(const ActualArgument &that) const {
return keyword == that.keyword &&
- isAlternateReturn == that.isAlternateReturn && value == that.value;
+ isAlternateReturn == that.isAlternateReturn && value() == that.value();
}
std::ostream &ActualArgument::AsFortran(std::ostream &o) const {
if (isAlternateReturn) {
o << '*';
}
- return value->AsFortran(o);
+ return value().AsFortran(o);
}
std::optional<int> ActualArgument::VectorSize() const {
namespace Fortran::evaluate {
-struct ActualArgument {
- explicit ActualArgument(Expr<SomeType> &&x) : value{std::move(x)} {}
+class ActualArgument {
+public:
+ explicit ActualArgument(Expr<SomeType> &&x) : value_{std::move(x)} {}
explicit ActualArgument(CopyableIndirection<Expr<SomeType>> &&v)
- : value{std::move(v)} {}
+ : value_{std::move(v)} {}
+
+ Expr<SomeType> &value() { return value_.value(); }
+ const Expr<SomeType> &value() const { return value_.value(); }
std::optional<DynamicType> GetType() const;
int Rank() const;
// TODO: Mark legacy %VAL and %REF arguments
+private:
// Subtlety: There is a distinction that must be maintained here between an
// actual argument expression that is a variable and one that is not,
// e.g. between X and (X). The parser attempts to parse each argument
// first as a variable, then as an expression, and the distinction appears
// in the parse tree.
- CopyableIndirection<Expr<SomeType>> value;
+ CopyableIndirection<Expr<SomeType>> value_;
};
using ActualArguments = std::vector<std::optional<ActualArgument>>;
std::ostream &DummyProcedure::Dump(std::ostream &o) const {
attrs.Dump(o, EnumToString);
- if (explicitProcedure.get() != nullptr) {
- explicitProcedure->Dump(o);
+ if (explicitProcedure.has_value()) {
+ explicitProcedure.value().Dump(o);
}
return o;
}
template<typename T>
std::ostream &Emit(std::ostream &o, const CopyableIndirection<Expr<T>> &expr) {
- return expr->AsFortran(o);
+ return expr.value().AsFortran(o);
}
template<typename T>
template<typename T>
std::ostream &Emit(std::ostream &o, const ImpliedDo<T> &implDo) {
o << '(';
- Emit(o, *implDo.values);
+ Emit(o, implDo.values());
o << ',' << ImpliedDoIndex::Result::AsFortran()
- << "::" << implDo.name.ToString() << '=';
- implDo.lower->AsFortran(o) << ',';
- implDo.upper->AsFortran(o) << ',';
- implDo.stride->AsFortran(o) << ')';
+ << "::" << implDo.name().ToString() << '=';
+ implDo.lower().AsFortran(o) << ',';
+ implDo.upper().AsFortran(o) << ',';
+ implDo.stride().AsFortran(o) << ')';
return o;
}
o << "z'" << x.Hexadecimal() << "'";
},
[&](const NullPointer &) { o << "NULL()"; },
- [&](const CopyableIndirection<Substring> &s) { s->AsFortran(o); },
+ [&](const CopyableIndirection<Substring> &s) {
+ s.value().AsFortran(o);
+ },
[&](const ImpliedDoIndex &i) { o << i.name.ToString(); },
[&](const auto &x) { x.AsFortran(o); },
},
template<typename T>
bool ImpliedDo<T>::operator==(const ImpliedDo<T> &that) const {
- return name == that.name && lower == that.lower && upper == that.upper &&
- stride == that.stride && values == that.values;
+ return name_ == that.name_ && lower_ == that.lower_ &&
+ upper_ == that.upper_ && stride_ == that.stride_ &&
+ values_ == that.values_;
}
template<typename R>
} else {
char ch{'('};
for (const auto &[symbol, value] : values_) {
- value->AsFortran(o << ch << symbol->name().ToString() << '=');
+ value.value().AsFortran(o << ch << symbol->name().ToString() << '=');
ch = ',';
}
}
template<int J> Expr<Operand<J>> &operand() {
if constexpr (operands == 1) {
static_assert(J == 0);
- return *operand_;
+ return operand_.value();
} else {
- return *std::get<J>(operand_);
+ return std::get<J>(operand_).value();
}
}
template<int J> const Expr<Operand<J>> &operand() const {
if constexpr (operands == 1) {
static_assert(J == 0);
- return *operand_;
+ return operand_.value();
} else {
- return *std::get<J>(operand_);
+ return std::get<J>(operand_).value();
}
}
parser::CharBlock name; // nested implied DOs must use distinct names
};
-template<typename RESULT> struct ImpliedDo {
+template<typename RESULT> class ImpliedDo {
+public:
using Result = RESULT;
+ using Index = ResultType<ImpliedDoIndex>;
+ ImpliedDo(parser::CharBlock name, Expr<Index> &&lower, Expr<Index> &&upper,
+ Expr<Index> &&stride, ArrayConstructorValues<Result> &&values)
+ : name_{name}, lower_{std::move(lower)}, upper_{std::move(upper)},
+ stride_{std::move(stride)}, values_{std::move(values)} {}
+ DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(ImpliedDo)
bool operator==(const ImpliedDo &) const;
- parser::CharBlock name;
- CopyableIndirection<Expr<ResultType<ImpliedDoIndex>>> lower, upper, stride;
- CopyableIndirection<ArrayConstructorValues<RESULT>> values;
+ parser::CharBlock name() const { return name_; }
+ Expr<Index> &lower() { return lower_.value(); }
+ const Expr<Index> &lower() const { return lower_.value(); }
+ Expr<Index> &upper() { return upper_.value(); }
+ const Expr<Index> &upper() const { return upper_.value(); }
+ Expr<Index> &stride() { return stride_.value(); }
+ const Expr<Index> &stride() const { return stride_.value(); }
+ ArrayConstructorValues<Result> &values() { return values_.value(); }
+ const ArrayConstructorValues<Result> &values() const {
+ return values_.value();
+ }
+
+private:
+ parser::CharBlock name_;
+ CopyableIndirection<Expr<Index>> lower_, upper_, stride_;
+ CopyableIndirection<ArrayConstructorValues<Result>> values_;
};
template<typename RESULT> struct ArrayConstructorValue {
bool operator==(const ArrayConstructor &) const;
static constexpr DynamicType GetType() { return Result::GetType(); }
std::ostream &AsFortran(std::ostream &) const;
- const Expr<SubscriptInteger> &LEN() const { return *length_; }
+ const Expr<SubscriptInteger> &LEN() const { return length_.value(); }
private:
CopyableIndirection<Expr<SubscriptInteger>> length_;
return std::visit(
common::visitors{
[&](IndirectSubscriptIntegerExpr &&expr) {
- *expr = Fold(context, std::move(*expr));
+ expr.value() = Fold(context, std::move(expr.value()));
return Subscript(std::move(expr));
},
[&](Triplet &&triplet) {
ActualArguments args{std::move(funcRef.arguments())};
for (std::optional<ActualArgument> &arg : args) {
if (arg.has_value()) {
- *arg->value = FoldOperation(context, std::move(*arg->value));
+ arg.value().value() =
+ FoldOperation(context, std::move(arg.value().value()));
}
}
if (auto *intrinsic{std::get_if<SpecificIntrinsic>(&funcRef.proc().u)}) {
std::string name{intrinsic->name};
if (name == "kind") {
if constexpr (common::HasMember<T, IntegerTypes>) {
- return Expr<T>{args[0]->value->GetType()->kind};
+ return Expr<T>{args[0].value().GetType()->kind};
} else {
common::die("kind() result not integral");
}
} else if (name == "len") {
if constexpr (std::is_same_v<T, SubscriptInteger>) {
- if (auto *charExpr{UnwrapExpr<Expr<SomeCharacter>>(*args[0]->value)}) {
+ if (auto *charExpr{UnwrapExpr<Expr<SomeCharacter>>(args[0].value())}) {
return std::visit([](auto &kx) { return kx.LEN(); }, charExpr->u);
}
} else {
private:
bool FoldArray(const CopyableIndirection<Expr<T>> &expr) {
- Expr<T> folded{Fold(context_, common::Clone(*expr))};
+ Expr<T> folded{Fold(context_, common::Clone(expr.value()))};
if (auto *c{UnwrapExpr<Constant<T>>(folded)}) {
// Copy elements in Fortran array element order
std::vector<std::int64_t> shape{c->shape()};
}
bool FoldArray(const ImpliedDo<T> &iDo) {
Expr<SubscriptInteger> lower{
- Fold(context_, Expr<SubscriptInteger>{*iDo.lower})};
+ Fold(context_, Expr<SubscriptInteger>{iDo.lower()})};
Expr<SubscriptInteger> upper{
- Fold(context_, Expr<SubscriptInteger>{*iDo.upper})};
+ Fold(context_, Expr<SubscriptInteger>{iDo.upper()})};
Expr<SubscriptInteger> stride{
- Fold(context_, Expr<SubscriptInteger>{*iDo.stride})};
+ Fold(context_, Expr<SubscriptInteger>{iDo.stride()})};
std::optional<std::int64_t> start{ToInt64(lower)}, end{ToInt64(upper)},
step{ToInt64(stride)};
if (start.has_value() && end.has_value() && step.has_value()) {
bool result{true};
- for (std::int64_t &j{context_.StartImpliedDo(iDo.name, *start)};
+ for (std::int64_t &j{context_.StartImpliedDo(iDo.name(), *start)};
j <= *end; j += *step) {
- result &= FoldArray(*iDo.values);
+ result &= FoldArray(iDo.values());
}
- context_.EndImpliedDo(iDo.name);
+ context_.EndImpliedDo(iDo.name());
return result;
} else {
return false;
FoldingContext &context, StructureConstructor &&structure) {
StructureConstructor result{structure.derivedTypeSpec()};
for (auto &&[symbol, value] : std::move(structure.values())) {
- result.Add(*symbol, Fold(context, std::move(*value)));
+ result.Add(*symbol, Fold(context, std::move(value.value())));
}
return Expr<SomeDerived>{Constant<SomeDerived>{result}};
}
}
template<typename V>
bool IsConstExpr(ConstExprContext &context, const ImpliedDo<V> &impliedDo) {
- if (!IsConstExpr(context, impliedDo.lower) ||
- !IsConstExpr(context, impliedDo.upper) ||
- !IsConstExpr(context, impliedDo.stride)) {
+ if (!IsConstExpr(context, impliedDo.lower()) ||
+ !IsConstExpr(context, impliedDo.upper()) ||
+ !IsConstExpr(context, impliedDo.stride())) {
return false;
}
ConstExprContext newContext{context};
- newContext.constantNames.insert(impliedDo.name);
- return IsConstExpr(newContext, impliedDo.values);
+ newContext.constantNames.insert(impliedDo.name());
+ return IsConstExpr(newContext, impliedDo.values());
}
template<typename A>
bool IsConstExpr(
return IsConstExpr(context, designator.u);
}
bool IsConstExpr(ConstExprContext &context, const ActualArgument &arg) {
- return IsConstExpr(context, *arg.value);
+ return IsConstExpr(context, arg.value());
}
template<typename A>
bool IsConstExpr(ConstExprContext &context, const FunctionRef<A> &funcRef) {
}
template<typename A>
bool IsConstExpr(ConstExprContext &context, const CopyableIndirection<A> &x) {
- return IsConstExpr(context, *x);
+ return IsConstExpr(context, x.value());
}
template<typename A>
bool IsConstExpr(ConstExprContext &context, const std::optional<A> &maybe) {
for (std::size_t j{0}; j < dummies; ++j) {
const IntrinsicDummyArgument &d{dummy[std::min(j, dummyArgPatterns - 1)]};
if (const ActualArgument * arg{actualForDummy[j]}) {
- if (IsAssumedRank(*arg->value) && d.rank != Rank::anyOrAssumedRank) {
+ if (IsAssumedRank(arg->value()) && d.rank != Rank::anyOrAssumedRank) {
messages.Say("assumed-rank array cannot be forwarded to "
"'%s=' argument"_err_en_US,
d.keyword);
CHECK(kindDummyArg != nullptr);
CHECK(result.categorySet == CategorySet{resultType->category});
if (kindArg != nullptr) {
- auto &expr{*kindArg->value};
+ auto &expr{kindArg->value()};
CHECK(expr.Rank() == 0);
if (auto code{ToInt64(expr)}) {
if (IsValidKindOfIntrinsicType(resultType->category, *code)) {
genericErrors.Say("unknown argument '%s' to NULL()"_err_en_US,
arguments[0]->keyword->ToString().data());
} else {
- Expr<SomeType> &mold{*arguments[0]->value};
+ Expr<SomeType> &mold{arguments[0]->value()};
if (IsPointerOrAllocatable(mold)) {
return std::make_optional<SpecificCall>(
SpecificIntrinsic{"null"s, mold.GetType(), mold.Rank(),
std::optional<Expr<SubscriptInteger>> Triplet::lower() const {
if (lower_) {
- return {**lower_};
+ return {lower_.value().value()};
}
return std::nullopt;
}
std::optional<Expr<SubscriptInteger>> Triplet::upper() const {
if (upper_) {
- return {**upper_};
+ return {upper_.value().value()};
}
return std::nullopt;
}
-const Expr<SubscriptInteger> &Triplet::stride() const { return *stride_; }
+const Expr<SubscriptInteger> &Triplet::stride() const {
+ return stride_.value();
+}
bool Triplet::IsStrideOne() const {
- if (auto stride{ToInt64(*stride_)}) {
+ if (auto stride{ToInt64(stride_.value())}) {
return stride == 1;
} else {
return false;
std::optional<Expr<SomeInteger>> CoarrayRef::stat() const {
if (stat_.has_value()) {
- return {**stat_};
+ return {stat_.value().value()};
} else {
return std::nullopt;
}
std::optional<Expr<SomeInteger>> CoarrayRef::team() const {
if (team_.has_value()) {
- return {**team_};
+ return {team_.value().value()};
} else {
return std::nullopt;
}
void Substring::SetBounds(std::optional<Expr<SubscriptInteger>> &lower,
std::optional<Expr<SubscriptInteger>> &upper) {
if (lower.has_value()) {
- lower_.emplace(std::move(*lower));
+ lower_.emplace(std::move(lower.value()));
}
if (upper.has_value()) {
- upper_.emplace(std::move(*upper));
+ upper_.emplace(std::move(upper.value()));
}
}
Expr<SubscriptInteger> Substring::lower() const {
if (lower_.has_value()) {
- return **lower_;
+ return lower_.value().value();
} else {
return AsExpr(Constant<SubscriptInteger>{1});
}
Expr<SubscriptInteger> Substring::upper() const {
if (upper_.has_value()) {
- return **upper_;
+ return upper_.value().value();
} else {
return std::visit(
common::visitors{
if (!lower_.has_value()) {
lower_ = AsExpr(Constant<SubscriptInteger>{1});
}
- *lower_ = evaluate::Fold(context, std::move(**lower_));
- std::optional<std::int64_t> lbi{ToInt64(**lower_)};
+ lower_.value() = evaluate::Fold(context, std::move(lower_.value().value()));
+ std::optional<std::int64_t> lbi{ToInt64(lower_.value().value())};
if (lbi.has_value() && *lbi < 1) {
context.messages().Say(
"lower bound (%jd) on substring is less than one"_en_US,
if (!upper_.has_value()) {
upper_ = upper();
}
- *upper_ = evaluate::Fold(context, std::move(**upper_));
- if (std::optional<std::int64_t> ubi{ToInt64(**upper_)}) {
+ upper_.value() = evaluate::Fold(context, std::move(upper_.value().value()));
+ if (std::optional<std::int64_t> ubi{ToInt64(upper_.value().value())}) {
auto *literal{std::get_if<StaticDataObject::Pointer>(&parent_)};
std::optional<std::int64_t> length;
if (literal != nullptr) {
if (kw != nullptr) {
o << kw;
}
- Emit(o, *p);
+ Emit(o, p.value());
return o;
}
}
std::ostream &Component::AsFortran(std::ostream &o) const {
- base_->AsFortran(o);
+ base_.value().AsFortran(o);
return Emit(o << '%', *symbol_);
}
std::ostream &Triplet::AsFortran(std::ostream &o) const {
Emit(o, lower_) << ':';
Emit(o, upper_);
- Emit(o << ':', *stride_);
+ Emit(o << ':', stride_.value());
return o;
}
if (int rank{symbol_->Rank()}; rank > 0) {
return rank;
}
- return base_->Rank();
+ return base_.value().Rank();
}
int Subscript::Rank() const {
return std::visit(
common::visitors{
- [](const IndirectSubscriptIntegerExpr &x) { return x->Rank(); },
+ [](const IndirectSubscriptIntegerExpr &x) {
+ return x.value().Rank();
+ },
[](const Triplet &) { return 1; },
},
u);
// GetBaseObject(), GetFirstSymbol(), & GetLastSymbol()
const Symbol &Component::GetFirstSymbol() const {
- return base_->GetFirstSymbol();
+ return base_.value().GetFirstSymbol();
}
const Symbol &ArrayRef::GetFirstSymbol() const {
}
bool Triplet::operator==(const Triplet &that) const {
return lower_ == that.lower_ && upper_ == that.upper_ &&
- *stride_ == *that.stride_;
+ stride_ == that.stride_;
}
bool ArrayRef::operator==(const ArrayRef &that) const {
return base_ == that.base_ && subscript_ == that.subscript_;
Component(CopyableIndirection<DataRef> &&b, const Symbol &c)
: base_{std::move(b)}, symbol_{&c} {}
- const DataRef &base() const { return *base_; }
- DataRef &base() { return *base_; }
+ const DataRef &base() const { return base_.value(); }
+ DataRef &base() { return base_.value(); }
int Rank() const;
const Symbol &GetFirstSymbol() const;
const Symbol &GetLastSymbol() const { return *symbol_; }
template<typename T, typename V>
void Walk(const common::Indirection<T> &x, V &visitor) {
- Walk(*x, visitor);
+ Walk(x.value(), visitor);
}
template<typename T, typename M>
void Walk(common::Indirection<T> &x, M &mutator) {
- Walk(*x, mutator);
+ Walk(x.value(), mutator);
}
// Walk a class with a single field 'thing'.
-// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
+// Copyright (c) 2018-2019, 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.
std::visit(
common::visitors{
[&](common::Indirection<Expr> &y) {
- args.push_back(std::move(*y));
+ args.push_back(std::move(y.value()));
},
[&](common::Indirection<Variable> &y) {
args.push_back(std::visit(
common::visitors{
[&](common::Indirection<Designator> &z) {
- return Expr{std::move(*z)};
+ return Expr{std::move(z.value())};
},
[&](common::Indirection<FunctionReference> &z) {
- return Expr{std::move(*z)};
+ return Expr{std::move(z.value())};
},
},
- y->u));
+ y.value().u));
},
[&](auto &) { CHECK(!"unexpected kind of ActualArg"); },
},
-// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
+// Copyright (c) 2018-2019, 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.
auto result{parser.Parse(state)};
if (result) {
if (auto *ustate{state.userState()}) {
- ustate->NewDoLabel(std::get<Label>(result->statement->t));
+ ustate->NewDoLabel(std::get<Label>(result->statement.value().t));
}
}
return result;
nested.Analyze(stmt.statement);
}
template<typename A> void Analyze(const common::Indirection<A> &x) {
- Analyze(*x);
+ Analyze(x.value());
}
template<typename... As> void Analyze(const std::variant<As...> &u) {
std::visit([&](const auto &x) { Analyze(x); }, u);
-// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
+// Copyright (c) 2018-2019, 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.
common::visitors{
[](auto &) {},
[&](Statement<common::Indirection<LabelDoStmt>> &labelDoStmt) {
- auto &label{std::get<Label>(labelDoStmt.statement->t)};
+ auto &label{std::get<Label>(labelDoStmt.statement.value().t)};
stack.push_back(LabelInfo{i, label});
},
[&](Statement<common::Indirection<EndDoStmt>> &endDoStmt) {
std::move(std::get<std::optional<LoopControl>>(
std::get<Statement<common::Indirection<LabelDoStmt>>>(
std::get<ExecutableConstruct>(doLoop->u).u)
- .statement->t)))}};
+ .statement.value()
+ .t)))}};
nonLabelDoStmt.source = originalSource;
std::get<ExecutableConstruct>(doLoop->u).u =
common::Indirection<DoConstruct>{
-// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
+// Copyright (c) 2018-2019, 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.
auto &logicalExpr{
std::get<parser::ScalarLogicalExpr>(optionalLoopControl->u)
.thing.thing};
- if (!ExpressionHasTypeCategory(
- *logicalExpr->typedExpr, common::TypeCategory::Logical)) {
+ if (!ExpressionHasTypeCategory(logicalExpr.value().typedExpr.value(),
+ common::TypeCategory::Logical)) {
messages_.Say(currentStatementSourcePosition_,
"DO WHERE must have LOGICAL expression"_err_en_US);
}
}
void CheckMaskIsPure(const parser::ScalarLogicalExpr &mask) const {
// C1121 - procedures in mask must be pure
- CS references{GatherReferencesFromExpression(*mask.thing.thing)};
+ CS references{GatherReferencesFromExpression(mask.thing.thing.value())};
for (auto *r : references) {
if (isProcedure(r->flags()) && !isPure(r->attrs())) {
messages_.Say(currentStatementSourcePosition_,
}
void HasNoReferences(
const CS &indexNames, const parser::ScalarIntExpr &expression) const {
- CS references{GatherReferencesFromExpression(*expression.thing.thing)};
+ CS references{
+ GatherReferencesFromExpression(expression.thing.thing.value())};
CheckNoCollisions(references, indexNames,
"concurrent-control expression references index-name"_err_en_US);
}
void CheckMaskDoesNotReferenceLocal(
const parser::ScalarLogicalExpr &mask, const CS &symbols) const {
// C1129
- CheckNoCollisions(GatherReferencesFromExpression(*mask.thing.thing),
+ CheckNoCollisions(GatherReferencesFromExpression(mask.thing.thing.value()),
symbols,
"concurrent-header mask-expr references name"
" in locality-spec"_err_en_US);
// C1123
HasNoReferences(indexNames, std::get<1>(c.t));
HasNoReferences(indexNames, std::get<2>(c.t));
- auto &expression{std::get<std::optional<parser::ScalarIntExpr>>(c.t)};
- if (expression) {
+ if (auto &expression{
+ std::get<std::optional<parser::ScalarIntExpr>>(c.t)}) {
HasNoReferences(indexNames, *expression);
}
}
if (std::visit(
common::visitors{
[&](IndirectSubscriptIntegerExpr &&x) {
- lower = std::move(*x);
+ lower = std::move(x.value());
return true;
},
[&](Triplet &&triplet) {
}
},
[&](const common::Indirection<parser::Expr> &expr) {
- auto restorer{
- exprContext_.GetContextualMessages().SetLocation(expr->source)};
- if (MaybeExpr v{exprContext_.Analyze(*expr)}) {
+ auto restorer{exprContext_.GetContextualMessages().SetLocation(
+ expr.value().source)};
+ if (MaybeExpr v{exprContext_.Analyze(expr.value())}) {
Push(std::move(*v));
}
},
[&](const common::Indirection<parser::AcImpliedDo> &impliedDo) {
const auto &control{
- std::get<parser::AcImpliedDoControl>(impliedDo->t)};
+ std::get<parser::AcImpliedDoControl>(impliedDo.value().t)};
const auto &bounds{
std::get<parser::LoopBounds<parser::ScalarIntExpr>>(control.t)};
parser::CharBlock name{bounds.name.thing.thing.source};
GetSpecificIntExpr<IntType::kind>(exprContext_, bounds.step)};
ArrayConstructorContext nested{*this};
for (const auto &value :
- std::get<std::list<parser::AcValue>>(impliedDo->t)) {
+ std::get<std::list<parser::AcValue>>(impliedDo.value().t)) {
nested.Add(value);
}
if (lower.has_value() && upper.has_value()) {
std::visit(
common::visitors{
[&](CopyableIndirection<Expr<SomeType>> &&expr) {
- auto *typed{UnwrapExpr<Expr<T>>(*expr)};
+ auto *typed{UnwrapExpr<Expr<T>>(expr.value())};
CHECK(typed != nullptr);
to.Push(std::move(*typed));
},
[&](ImpliedDo<SomeType> &&impliedDo) {
- to.Push(ImpliedDo<T>{impliedDo.name, std::move(*impliedDo.lower),
- std::move(*impliedDo.upper), std::move(*impliedDo.stride),
- MakeSpecific<T>(std::move(*impliedDo.values))});
+ to.Push(ImpliedDo<T>{impliedDo.name(),
+ std::move(impliedDo.lower()), std::move(impliedDo.upper()),
+ std::move(impliedDo.stride()),
+ MakeSpecific<T>(std::move(impliedDo.values()))});
},
},
std::move(x.u));
for (const auto &component :
std::get<std::list<parser::ComponentSpec>>(structure.t)) {
const parser::Expr &expr{
- *std::get<parser::ComponentDataSource>(component.t).v};
+ std::get<parser::ComponentDataSource>(component.t).v.value()};
parser::CharBlock source{expr.source};
const Symbol *symbol{nullptr};
if (const auto &kw{std::get<std::optional<parser::Keyword>>(component.t)}) {
std::visit(
common::visitors{
[&](const common::Indirection<parser::Variable> &v) {
- actualArgExpr = AnalyzeExpr(context, *v);
+ actualArgExpr = AnalyzeExpr(context, v.value());
},
[&](const common::Indirection<parser::Expr> &x) {
- actualArgExpr = AnalyzeExpr(context, *x);
+ actualArgExpr = AnalyzeExpr(context, x.value());
},
[&](const parser::Name &n) {
context.Say("TODO: procedure name actual arg"_err_en_US);
ExpressionAnalysisContext &context, const parser::Expr::Parentheses &x) {
// TODO: C1003: A parenthesized function reference may not return a
// procedure pointer.
- if (MaybeExpr operand{AnalyzeExpr(context, *x.v)}) {
+ if (MaybeExpr operand{AnalyzeExpr(context, x.v.value())}) {
return std::visit(
common::visitors{
[&](BOZLiteralConstant &&boz) {
static MaybeExpr AnalyzeExpr(
ExpressionAnalysisContext &context, const parser::Expr::UnaryPlus &x) {
- MaybeExpr value{AnalyzeExpr(context, *x.v)};
+ MaybeExpr value{AnalyzeExpr(context, x.v.value())};
if (value.has_value()) {
std::visit(
common::visitors{
static MaybeExpr AnalyzeExpr(
ExpressionAnalysisContext &context, const parser::Expr::Negate &x) {
- if (MaybeExpr operand{AnalyzeExpr(context, *x.v)}) {
+ if (MaybeExpr operand{AnalyzeExpr(context, x.v.value())}) {
return Negation(context.GetContextualMessages(), std::move(*operand));
}
return std::nullopt;
static MaybeExpr AnalyzeExpr(
ExpressionAnalysisContext &context, const parser::Expr::NOT &x) {
- if (MaybeExpr operand{AnalyzeExpr(context, *x.v)}) {
+ if (MaybeExpr operand{AnalyzeExpr(context, x.v.value())}) {
return std::visit(
common::visitors{
[](Expr<SomeLogical> &&lx) -> MaybeExpr {
template<template<typename> class OPR, typename PARSED>
MaybeExpr BinaryOperationHelper(
ExpressionAnalysisContext &context, const PARSED &x) {
- if (auto both{common::AllPresent(AnalyzeExpr(context, *std::get<0>(x.t)),
- AnalyzeExpr(context, *std::get<1>(x.t)))}) {
+ if (auto both{
+ common::AllPresent(AnalyzeExpr(context, std::get<0>(x.t).value()),
+ AnalyzeExpr(context, std::get<1>(x.t).value()))}) {
ConformabilityCheck(context.GetContextualMessages(), std::get<0>(*both),
std::get<1>(*both));
return NumericOperation<OPR>(context.GetContextualMessages(),
static MaybeExpr AnalyzeExpr(ExpressionAnalysisContext &context,
const parser::Expr::ComplexConstructor &x) {
- auto re{AnalyzeExpr(context, *std::get<0>(x.t))};
- auto im{AnalyzeExpr(context, *std::get<1>(x.t))};
+ auto re{AnalyzeExpr(context, std::get<0>(x.t).value())};
+ auto im{AnalyzeExpr(context, std::get<1>(x.t).value())};
if (re.has_value() && im.has_value()) {
ConformabilityCheck(context.GetContextualMessages(), *re, *im);
}
static MaybeExpr AnalyzeExpr(
ExpressionAnalysisContext &context, const parser::Expr::Concat &x) {
- if (auto both{common::AllPresent(AnalyzeExpr(context, *std::get<0>(x.t)),
- AnalyzeExpr(context, *std::get<1>(x.t)))}) {
+ if (auto both{
+ common::AllPresent(AnalyzeExpr(context, std::get<0>(x.t).value()),
+ AnalyzeExpr(context, std::get<1>(x.t).value()))}) {
ConformabilityCheck(context.GetContextualMessages(), std::get<0>(*both),
std::get<1>(*both));
return std::visit(
template<typename PARSED>
MaybeExpr RelationHelper(ExpressionAnalysisContext &context,
RelationalOperator opr, const PARSED &x) {
- if (auto both{common::AllPresent(AnalyzeExpr(context, *std::get<0>(x.t)),
- AnalyzeExpr(context, *std::get<1>(x.t)))}) {
+ if (auto both{
+ common::AllPresent(AnalyzeExpr(context, std::get<0>(x.t).value()),
+ AnalyzeExpr(context, std::get<1>(x.t).value()))}) {
ConformabilityCheck(context.GetContextualMessages(), std::get<0>(*both),
std::get<1>(*both));
return AsMaybeExpr(Relate(context.GetContextualMessages(), opr,
template<typename PARSED>
MaybeExpr LogicalHelper(
ExpressionAnalysisContext &context, LogicalOperator opr, const PARSED &x) {
- if (auto both{common::AllPresent(AnalyzeExpr(context, *std::get<0>(x.t)),
- AnalyzeExpr(context, *std::get<1>(x.t)))}) {
+ if (auto both{
+ common::AllPresent(AnalyzeExpr(context, std::get<0>(x.t).value()),
+ AnalyzeExpr(context, std::get<1>(x.t).value()))}) {
return std::visit(
common::visitors{
[&](Expr<SomeLogical> &&lx, Expr<SomeLogical> &&ly) -> MaybeExpr {
}
MaybeExpr ExpressionAnalysisContext::Analyze(const parser::Expr &expr) {
- if (const auto *typed{expr.typedExpr.get()}) {
+ if (expr.typedExpr.has_value()) {
// Expression was already checked by AnalyzeExpressions() below.
- return std::make_optional<Expr<SomeType>>(typed->v);
+ return std::make_optional<Expr<SomeType>>(expr.typedExpr.value().v);
} else if (!expr.source.empty()) {
// Analyze the expression in a specified source position context for better
// error reporting.
template<typename A> void Post(const A &) {}
bool Pre(const parser::Expr &expr) {
- if (expr.typedExpr.get() == nullptr) {
+ if (!expr.typedExpr.has_value()) {
if (MaybeExpr checked{AnalyzeExpr(context_, expr)}) {
#if PMKDEBUG
// checked->AsFortran(std::cout << "checked expression: ") << '\n';
template<typename A>
std::optional<Expr<SomeType>> AnalyzeExpr(
ExpressionAnalysisContext &context, const common::Indirection<A> &x) {
- return AnalyzeExpr(context, *x);
+ return AnalyzeExpr(context, x.value());
}
// These specializations implement constraint checking.
CHECK(program.v.size() == 1);
auto &unit{program.v.front()};
auto &submod{std::get<common::Indirection<parser::Submodule>>(unit.u)};
- auto &stmt{std::get<parser::Statement<parser::SubmoduleStmt>>(submod->t)};
+ auto &stmt{
+ std::get<parser::Statement<parser::SubmoduleStmt>>(submod.value().t)};
auto &parentId{std::get<parser::ParentIdentifier>(stmt.statement.t)};
if (auto &parent{std::get<std::optional<parser::Name>>(parentId.t)}) {
return &parent->source;
[&](const parser::Name &name) { AddUse(name); },
[](const auto &) { common::die("TODO: GenericSpec"); },
},
- generic->u);
+ generic.value().u);
},
[&](const parser::Name &name) { AddUse(name); },
[&](const parser::Rename &rename) {
specificProcs.push_back(symbol);
}
}
- const auto *genericName{GetGenericSpecName(*genericSpec)};
+ const auto *genericName{GetGenericSpecName(genericSpec.value())};
if (!genericName) {
return false;
}
bool ConstructVisitor::Pre(const parser::DataStmtObject &x) {
std::visit(
common::visitors{
- [&](const common::Indirection<parser::Variable> &y) { Walk(*y); },
+ [&](const common::Indirection<parser::Variable> &y) {
+ Walk(y.value());
+ },
[&](const parser::DataImpliedDo &y) {
PushScope(Scope::Kind::ImpliedDos, nullptr);
Walk(y);
[&](const parser::Variable &y) {
if (const auto *des{
std::get_if<Indirection<parser::Designator>>(&y.u)}) {
- if (const auto *dr{std::get_if<parser::DataRef>(&(*des)->u)}) {
+ if (const auto *dr{
+ std::get_if<parser::DataRef>(&des->value().u)}) {
variable = std::get_if<parser::Name>(&dr->u);
if (variable && !FindSymbol(*variable)) {
variable = nullptr;
common::visitors{
[=](const parser::Name &y) { return ResolveName(y); },
[=](const Indirection<parser::StructureComponent> &y) {
- return ResolveStructureComponent(*y);
+ return ResolveStructureComponent(y.value());
},
[=](const Indirection<parser::ArrayElement> &y) {
- return ResolveArrayElement(*y);
+ return ResolveArrayElement(y.value());
},
[=](const Indirection<parser::CoindexedNamedObject> &y) {
- return ResolveCoindexedNamedObject(*y);
+ return ResolveCoindexedNamedObject(y.value());
},
},
x.u);
},
[](const auto &) { common::die("TODO: GenericSpec"); },
},
- y->u);
+ y.value().u);
},
},
accessId.u);
},
[](const auto &) -> const parser::Name * { return nullptr; },
},
- (*designator)->u)}) {
+ designator->value().u)}) {
return !NameIsKnownOrIntrinsic(*name);
}
}
return;
}
parser::Name *name{std::get_if<parser::Name>(
- &std::get<parser::ProcedureDesignator>((*funcRef)->v.t).u)};
+ &std::get<parser::ProcedureDesignator>(funcRef->value().v.t).u)};
if (!name || !name->symbol ||
!name->symbol->GetUltimate().has<ObjectEntityDetails>()) {
return;
}
- x.u = common::Indirection{(*funcRef)->ConvertToArrayElementRef()};
+ x.u = common::Indirection{funcRef->value().ConvertToArrayElementRef()};
}
};
auto &list{std::get<std::list<parser::DeclarationConstruct>>(x.t)};
for (auto it{list.begin()}; it != list.end();) {
if (auto stmt{std::get_if<stmtFuncType>(&it->u)}) {
- Symbol *symbol{std::get<parser::Name>(stmt->statement->t).symbol};
+ Symbol *symbol{std::get<parser::Name>(stmt->statement.value().t).symbol};
if (symbol && symbol->has<ObjectEntityDetails>()) {
// not a stmt func: remove it here and add to ones to convert
stmtFuncsToConvert_.push_back(std::move(*stmt));
bool RewriteMutator::Pre(parser::ExecutionPart &x) {
auto origFirst{x.v.begin()}; // insert each elem before origFirst
for (stmtFuncType &sf : stmtFuncsToConvert_) {
- auto &&stmt = sf.statement->ConvertToAssignment();
+ auto &&stmt = sf.statement.value().ConvertToAssignment();
stmt.source = sf.source;
x.v.insert(origFirst,
parser::ExecutionPartConstruct{parser::ExecutableConstruct{stmt}});