[flang] Use value()/has_value() on Indirection class templates instead of operator...
authorpeter klausler <pklausler@nvidia.com>
Tue, 5 Mar 2019 20:28:08 +0000 (12:28 -0800)
committerpeter klausler <pklausler@nvidia.com>
Tue, 5 Mar 2019 20:28:08 +0000 (12:28 -0800)
Original-commit: flang-compiler/f18@a97f377ae6051d877df82036983cc6209a2e0d95
Reviewed-on: https://github.com/flang-compiler/f18/pull/311
Tree-same-pre-rewrite: false

21 files changed:
flang/lib/common/indirection.h
flang/lib/evaluate/call.cc
flang/lib/evaluate/call.h
flang/lib/evaluate/characteristics.cc
flang/lib/evaluate/expression.cc
flang/lib/evaluate/expression.h
flang/lib/evaluate/fold.cc
flang/lib/evaluate/intrinsics.cc
flang/lib/evaluate/variable.cc
flang/lib/evaluate/variable.h
flang/lib/parser/parse-tree-visitor.h
flang/lib/parser/parse-tree.cc
flang/lib/parser/user-state.cc
flang/lib/semantics/assignment.cc
flang/lib/semantics/canonicalize-do.cc
flang/lib/semantics/check-do-concurrent.cc
flang/lib/semantics/expression.cc
flang/lib/semantics/expression.h
flang/lib/semantics/mod-file.cc
flang/lib/semantics/resolve-names.cc
flang/lib/semantics/rewrite-parse-tree.cc

index a04404f..c35f10f 100644 (file)
@@ -65,10 +65,6 @@ public:
 
   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_; }
@@ -120,10 +116,6 @@ public:
 
   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_; }
@@ -168,12 +160,15 @@ public:
     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 {
@@ -224,11 +219,6 @@ public:
     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_; }
 
index b4c7de4..aefb901 100644 (file)
 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 {
@@ -36,7 +36,7 @@ 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 {
index 8f0ea85..b0b39f8 100644 (file)
@@ -31,10 +31,14 @@ class Symbol;
 
 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;
@@ -47,12 +51,13 @@ struct ActualArgument {
 
   // 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>>;
index b44f98e..79dad84 100644 (file)
@@ -61,8 +61,8 @@ bool DummyProcedure::operator==(const DummyProcedure &that) const {
 
 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;
 }
index 857d876..0f4f068 100644 (file)
@@ -87,7 +87,7 @@ std::ostream &LogicalOperation<KIND>::Infix(std::ostream &o) const {
 
 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>
@@ -96,12 +96,12 @@ std::ostream &Emit(std::ostream &, const ArrayConstructorValues<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;
 }
 
@@ -147,7 +147,9 @@ std::ostream &ExpressionBase<RESULT>::AsFortran(std::ostream &o) const {
             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); },
       },
@@ -235,8 +237,9 @@ bool ImpliedDoIndex::operator==(const ImpliedDoIndex &that) const {
 
 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>
@@ -288,7 +291,7 @@ std::ostream &StructureConstructor::AsFortran(std::ostream &o) const {
   } 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 = ',';
     }
   }
index 9367766..b904e72 100644 (file)
@@ -145,17 +145,17 @@ public:
   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();
     }
   }
 
@@ -413,12 +413,32 @@ struct ImpliedDoIndex {
   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 {
@@ -466,7 +486,7 @@ public:
   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_;
index b9241fe..491313d 100644 (file)
@@ -79,7 +79,7 @@ Subscript FoldOperation(FoldingContext &context, Subscript &&subscript) {
   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) {
@@ -161,20 +161,21 @@ Expr<T> FoldOperation(FoldingContext &context, FunctionRef<T> &&funcRef) {
   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 {
@@ -250,7 +251,7 @@ public:
 
 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()};
@@ -276,20 +277,20 @@ private:
   }
   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;
@@ -322,7 +323,7 @@ Expr<SomeDerived> FoldOperation(
     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}};
 }
@@ -882,14 +883,14 @@ bool IsConstExpr(
 }
 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(
@@ -967,7 +968,7 @@ bool IsConstExpr(ConstExprContext &context, const Designator<A> &designator) {
   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) {
@@ -987,7 +988,7 @@ bool IsConstExpr(ConstExprContext &context, const Expr<A> &expr) {
 }
 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) {
index 6f9be43..b645385 100644 (file)
@@ -944,7 +944,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
   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);
@@ -1069,7 +1069,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
       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)) {
@@ -1263,7 +1263,7 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
       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(),
index a931f5b..05fae73 100644 (file)
@@ -45,22 +45,24 @@ Triplet::Triplet(std::optional<Expr<SubscriptInteger>> &&l,
 
 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;
@@ -77,7 +79,7 @@ CoarrayRef::CoarrayRef(std::vector<const Symbol *> &&c,
 
 std::optional<Expr<SomeInteger>> CoarrayRef::stat() const {
   if (stat_.has_value()) {
-    return {**stat_};
+    return {stat_.value().value()};
   } else {
     return std::nullopt;
   }
@@ -85,7 +87,7 @@ std::optional<Expr<SomeInteger>> CoarrayRef::stat() const {
 
 std::optional<Expr<SomeInteger>> CoarrayRef::team() const {
   if (team_.has_value()) {
-    return {**team_};
+    return {team_.value().value()};
   } else {
     return std::nullopt;
   }
@@ -107,16 +109,16 @@ CoarrayRef &CoarrayRef::set_team(Expr<SomeInteger> &&v, bool isTeamNumber) {
 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});
   }
@@ -124,7 +126,7 @@ Expr<SubscriptInteger> Substring::lower() const {
 
 Expr<SubscriptInteger> Substring::upper() const {
   if (upper_.has_value()) {
-    return **upper_;
+    return upper_.value().value();
   } else {
     return std::visit(
         common::visitors{
@@ -141,8 +143,8 @@ std::optional<Expr<SomeCharacter>> Substring::Fold(FoldingContext &context) {
   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,
@@ -153,8 +155,8 @@ std::optional<Expr<SomeCharacter>> Substring::Fold(FoldingContext &context) {
   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) {
@@ -262,7 +264,7 @@ std::ostream &Emit(std::ostream &o, const CopyableIndirection<A> &p,
   if (kw != nullptr) {
     o << kw;
   }
-  Emit(o, *p);
+  Emit(o, p.value());
   return o;
 }
 
@@ -298,14 +300,14 @@ std::ostream &TypeParamInquiry<KIND>::AsFortran(std::ostream &o) const {
 }
 
 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;
 }
 
@@ -465,13 +467,15 @@ int Component::Rank() const {
   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);
@@ -538,7 +542,7 @@ template<typename T> int Designator<T>::Rank() const {
 
 // GetBaseObject(), GetFirstSymbol(), & GetLastSymbol()
 const Symbol &Component::GetFirstSymbol() const {
-  return base_->GetFirstSymbol();
+  return base_.value().GetFirstSymbol();
 }
 
 const Symbol &ArrayRef::GetFirstSymbol() const {
@@ -658,7 +662,7 @@ bool TypeParamInquiry<KIND>::operator==(
 }
 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_;
index c51fafc..ef280e1 100644 (file)
@@ -80,8 +80,8 @@ public:
   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_; }
index ae1181f..7c9e2ae 100644 (file)
@@ -221,11 +221,11 @@ std::enable_if_t<WrapperTrait<A>> Walk(A &x, M &mutator) {
 
 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'.
index efa0ece..f4894fa 100644 (file)
@@ -1,4 +1,4 @@
-// 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.
@@ -96,19 +96,19 @@ Designator FunctionReference::ConvertToArrayElementRef() {
     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"); },
         },
index a913a29..9b1e4b1 100644 (file)
@@ -1,4 +1,4 @@
-// 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.
@@ -36,7 +36,7 @@ std::optional<CapturedLabelDoStmt::resultType> CapturedLabelDoStmt::Parse(
   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;
index 18c97f6..2defa86 100644 (file)
@@ -103,7 +103,7 @@ public:
     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);
index 52cf6aa..3e3c382 100644 (file)
@@ -1,4 +1,4 @@
-// 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.
@@ -34,7 +34,7 @@ public:
             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) {
@@ -74,7 +74,8 @@ private:
                 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>{
index a4a5519..527a790 100644 (file)
@@ -1,4 +1,4 @@
-// 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.
@@ -345,8 +345,8 @@ public:
         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);
         }
@@ -392,7 +392,7 @@ private:
   }
   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_,
@@ -415,7 +415,8 @@ private:
   }
   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);
   }
@@ -435,7 +436,7 @@ private:
   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);
@@ -478,8 +479,8 @@ private:
         // 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);
         }
       }
index 802a426..c6b6e85 100644 (file)
@@ -348,7 +348,7 @@ static MaybeExpr ResolveAmbiguousSubstring(
       if (std::visit(
               common::visitors{
                   [&](IndirectSubscriptIntegerExpr &&x) {
-                    lower = std::move(*x);
+                    lower = std::move(x.value());
                     return true;
                   },
                   [&](Triplet &&triplet) {
@@ -1258,15 +1258,15 @@ void ArrayConstructorContext::Add(const parser::AcValue &x) {
             }
           },
           [&](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};
@@ -1289,7 +1289,7 @@ void ArrayConstructorContext::Add(const parser::AcValue &x) {
                 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()) {
@@ -1318,14 +1318,15 @@ ArrayConstructorValues<T> MakeSpecific(
     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));
@@ -1416,7 +1417,7 @@ static MaybeExpr AnalyzeExpr(ExpressionAnalysisContext &context,
   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)}) {
@@ -1627,10 +1628,10 @@ static MaybeExpr AnalyzeExpr(ExpressionAnalysisContext &context,
     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);
@@ -1687,7 +1688,7 @@ static MaybeExpr AnalyzeExpr(
     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) {
@@ -1716,7 +1717,7 @@ static MaybeExpr AnalyzeExpr(
 
 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{
@@ -1740,7 +1741,7 @@ static MaybeExpr AnalyzeExpr(
 
 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;
@@ -1748,7 +1749,7 @@ static MaybeExpr AnalyzeExpr(
 
 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 {
@@ -1784,8 +1785,9 @@ static MaybeExpr AnalyzeExpr(
 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(),
@@ -1822,8 +1824,8 @@ static MaybeExpr AnalyzeExpr(
 
 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);
   }
@@ -1834,8 +1836,9 @@ static MaybeExpr AnalyzeExpr(ExpressionAnalysisContext &context,
 
 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(
@@ -1870,8 +1873,9 @@ static MaybeExpr AnalyzeExpr(
 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,
@@ -1914,8 +1918,9 @@ static MaybeExpr AnalyzeExpr(
 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 {
@@ -1969,9 +1974,9 @@ static MaybeExpr AnalyzeExpr(
 }
 
 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.
@@ -2092,7 +2097,7 @@ public:
   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';
index ad61948..f865c08 100644 (file)
@@ -152,7 +152,7 @@ std::optional<Expr<SomeType>> AnalyzeExpr(
 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.
index 1f0d38f..329ed8b 100644 (file)
@@ -682,7 +682,8 @@ static const SourceName *GetSubmoduleParent(const parser::Program &program) {
   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;
index 0340a06..a4f09c2 100644 (file)
@@ -1762,7 +1762,7 @@ bool ModuleVisitor::Pre(const parser::Only &x) {
                     [&](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) {
@@ -3241,7 +3241,7 @@ bool DeclarationVisitor::Pre(const parser::TypeBoundGenericStmt &x) {
       specificProcs.push_back(symbol);
     }
   }
-  const auto *genericName{GetGenericSpecName(*genericSpec)};
+  const auto *genericName{GetGenericSpecName(genericSpec.value())};
   if (!genericName) {
     return false;
   }
@@ -3906,7 +3906,9 @@ bool ConstructVisitor::Pre(const parser::DataImpliedDo &x) {
 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);
@@ -3992,7 +3994,8 @@ void ConstructVisitor::Post(const parser::Selector &x) {
           [&](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;
@@ -4236,13 +4239,13 @@ const parser::Name *ResolveNamesVisitor::ResolveDataRef(
       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);
@@ -4447,7 +4450,7 @@ bool ModuleVisitor::Pre(const parser::AccessStmt &x) {
                         },
                         [](const auto &) { common::die("TODO: GenericSpec"); },
                     },
-                    y->u);
+                    y.value().u);
               },
           },
           accessId.u);
@@ -4594,7 +4597,7 @@ bool ResolveNamesVisitor::Pre(const parser::PointerAssignmentStmt &x) {
                 },
                 [](const auto &) -> const parser::Name * { return nullptr; },
             },
-            (*designator)->u)}) {
+            designator->value().u)}) {
       return !NameIsKnownOrIntrinsic(*name);
     }
   }
index 841ca5e..9193f17 100644 (file)
@@ -73,12 +73,12 @@ private:
       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()};
   }
 };
 
@@ -95,7 +95,7 @@ void RewriteMutator::Post(parser::SpecificationPart &x) {
   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));
@@ -111,7 +111,7 @@ void RewriteMutator::Post(parser::SpecificationPart &x) {
 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}});