[flang] clean up CoarrayRef
authorpeter klausler <pklausler@nvidia.com>
Wed, 3 Apr 2019 19:57:24 +0000 (12:57 -0700)
committerpeter klausler <pklausler@nvidia.com>
Fri, 5 Apr 2019 19:56:03 +0000 (12:56 -0700)
Original-commit: flang-compiler/f18@41bef37c7c859ae87ebe56f730cb43703c58da25
Reviewed-on: https://github.com/flang-compiler/f18/pull/386
Tree-same-pre-rewrite: false

flang/lib/evaluate/descender.h
flang/lib/evaluate/fold.cc
flang/lib/evaluate/formatting.cc
flang/lib/evaluate/shape.cc
flang/lib/evaluate/variable.cc
flang/lib/evaluate/variable.h

index 42aed26..d4d8c25 100644 (file)
@@ -210,23 +210,16 @@ public:
     Visit(aref.subscript());
   }
 
-  void Descend(const CoarrayRef::BasePartRef &part) {
-    Visit(*part.symbol);
-    Visit(part.subscript);
-  }
-  void Descend(CoarrayRef::BasePartRef &part) {
-    Visit(*part.symbol);
-    Visit(part.subscript);
-  }
-
   void Descend(const CoarrayRef &caref) {
-    Visit(caref.baseDataRef());
+    Visit(caref.base());
+    Visit(caref.subscript());
     Visit(caref.cosubscript());
     Visit(caref.stat());
     Visit(caref.team());
   }
   void Descend(CoarrayRef &caref) {
-    Visit(caref.baseDataRef());
+    Visit(caref.base());
+    Visit(caref.subscript());
     Visit(caref.cosubscript());
     Visit(caref.stat());
     Visit(caref.team());
index df32195..dd4e13e 100644 (file)
@@ -113,19 +113,16 @@ ArrayRef FoldOperation(FoldingContext &context, ArrayRef &&arrayRef) {
 }
 
 CoarrayRef FoldOperation(FoldingContext &context, CoarrayRef &&coarrayRef) {
-  CoarrayRef::BaseDataRef baseDataRef;
-  for (auto &&part : std::move(coarrayRef.baseDataRef())) {
-    baseDataRef.emplace_back(*coarrayRef.baseDataRef().front().symbol);
-    for (auto &&subscript : std::move(part.subscript)) {
-      baseDataRef.back().subscript.emplace_back(
-          Fold(context, std::move(subscript)));
-    }
+  std::vector<Subscript> subscript;
+  for (Subscript x : coarrayRef.subscript()) {
+    subscript.emplace_back(FoldOperation(context, std::move(x)));
   }
   std::vector<Expr<SubscriptInteger>> cosubscript;
   for (Expr<SubscriptInteger> x : coarrayRef.cosubscript()) {
     cosubscript.emplace_back(Fold(context, std::move(x)));
   }
-  CoarrayRef folded{std::move(baseDataRef), std::move(cosubscript)};
+  CoarrayRef folded{std::move(coarrayRef.base()), std::move(subscript),
+      std::move(cosubscript)};
   if (std::optional<Expr<SomeInteger>> stat{coarrayRef.stat()}) {
     folded.set_stat(Fold(context, std::move(*stat)));
   }
index 9560e45..3542a12 100644 (file)
@@ -511,23 +511,23 @@ std::ostream &ArrayRef::AsFortran(std::ostream &o) const {
 
 std::ostream &CoarrayRef::AsFortran(std::ostream &o) const {
   bool first{true};
-  for (const auto &part : baseDataRef_) {
+  for (const Symbol *part : base_) {
     if (first) {
       first = false;
     } else {
       o << '%';
     }
-    EmitVar(o, *part.symbol);
-    char ch{'('};
-    for (const auto &sscript : part.subscript) {
-      EmitVar(o << ch, sscript);
-      ch = ',';
-    }
-    if (ch == ',') {
-      o << ')';
-    }
+    EmitVar(o, *part);
+  }
+  char separator{'('};
+  for (const auto &sscript : subscript_) {
+    EmitVar(o << separator, sscript);
+    separator = ',';
+  }
+  if (separator == ',') {
+    o << ')';
   }
-  char separator{'['};
+  separator = '[';
   for (const auto &css : cosubscript_) {
     EmitVar(o << separator, css);
     separator = ',';
index 666846f..63b1663 100644 (file)
@@ -87,12 +87,10 @@ static Extent GetExtent(const Subscript &subscript) {
       subscript.u);
 }
 std::optional<Shape> GetShape(const ArrayRef &arrayRef) {
-  int subscripts{arrayRef.size()};
   Shape shape;
-  for (int j = 0; j < subscripts; ++j) {
-    const Subscript &subscript{arrayRef.at(j)};
-    if (subscript.Rank() > 0) {
-      shape.emplace_back(GetExtent(subscript));
+  for (const Subscript &ss : arrayRef.subscript()) {
+    if (ss.Rank() > 0) {
+      shape.emplace_back(GetExtent(ss));
     }
   }
   if (shape.empty()) {
@@ -101,7 +99,19 @@ std::optional<Shape> GetShape(const ArrayRef &arrayRef) {
     return shape;
   }
 }
-std::optional<Shape> GetShape(const CoarrayRef &);  // TODO pmk
+std::optional<Shape> GetShape(const CoarrayRef &coarrayRef) {
+  Shape shape;
+  for (const Subscript &ss : coarrayRef.subscript()) {
+    if (ss.Rank() > 0) {
+      shape.emplace_back(GetExtent(ss));
+    }
+  }
+  if (shape.empty()) {
+    return GetShape(coarrayRef.GetLastSymbol());
+  } else {
+    return shape;
+  }
+}
 std::optional<Shape> GetShape(const DataRef &dataRef) {
   return std::visit([](const auto &x) { return GetShape(x); }, dataRef.u);
 }
index 3165e35..8f1a7e8 100644 (file)
@@ -69,14 +69,15 @@ bool Triplet::IsStrideOne() const {
   }
 }
 
-bool CoarrayRef::BasePartRef::operator==(const BasePartRef &that) const {
-  return symbol == that.symbol && subscript == that.subscript;
-}
-
-CoarrayRef::CoarrayRef(
-    CoarrayRef::BaseDataRef &&base, std::vector<Expr<SubscriptInteger>> &&css)
-  : baseDataRef_{std::move(base)}, cosubscript_(std::move(css)) {
-  CHECK(!baseDataRef_.empty());
+CoarrayRef::CoarrayRef(std::vector<const Symbol *> &&base,
+    std::vector<Subscript> &&ss, std::vector<Expr<SubscriptInteger>> &&css)
+  : base_{std::move(base)}, subscript_(std::move(ss)),
+    cosubscript_(std::move(css)) {
+  CHECK(!base_.empty());
+  for (const Symbol *symbol : base_) {
+    CHECK(symbol != nullptr);
+  }
+  CHECK(!cosubscript_.empty());
 }
 
 std::optional<Expr<SomeInteger>> CoarrayRef::stat() const {
@@ -108,13 +109,9 @@ CoarrayRef &CoarrayRef::set_team(Expr<SomeInteger> &&v, bool isTeamNumber) {
   return *this;
 }
 
-const Symbol &CoarrayRef::GetFirstSymbol() const {
-  return *baseDataRef_.front().symbol;
-}
+const Symbol &CoarrayRef::GetFirstSymbol() const { return *base_.front(); }
 
-const Symbol &CoarrayRef::GetLastSymbol() const {
-  return *baseDataRef_.back().symbol;
-}
+const Symbol &CoarrayRef::GetLastSymbol() const { return *base_.back(); }
 
 void Substring::SetBounds(std::optional<Expr<SubscriptInteger>> &lower,
     std::optional<Expr<SubscriptInteger>> &upper) {
@@ -362,12 +359,24 @@ int ArrayRef::Rank() const {
   }
   return std::visit(
       common::visitors{
-          [=](const Symbol *s) { return 0; },
+          [=](const Symbol *s) { return s->Rank(); },
           [=](const Component &c) { return c.Rank(); },
       },
       base_);
 }
 
+int CoarrayRef::Rank() const {
+  int rank{0};
+  for (const auto &expr : subscript_) {
+    rank += expr.Rank();
+  }
+  if (rank > 0) {
+    return rank;
+  } else {
+    return base_.back()->Rank();
+  }
+}
+
 int DataRef::Rank() const {
   return std::visit(
       // g++ 7.2 emits bogus warnings here and below when common::visitors{}
@@ -531,7 +540,7 @@ bool ArrayRef::operator==(const ArrayRef &that) const {
   return base_ == that.base_ && subscript_ == that.subscript_;
 }
 bool CoarrayRef::operator==(const CoarrayRef &that) const {
-  return baseDataRef_ == that.baseDataRef_ &&
+  return base_ == that.base_ && subscript_ == that.subscript_ &&
       cosubscript_ == that.cosubscript_ && stat_ == that.stat_ &&
       team_ == that.team_ && teamIsTeamNumber_ == that.teamIsTeamNumber_;
 }
index 94386d9..14ddf5f 100644 (file)
@@ -205,30 +205,22 @@ private:
 // components: they can't be pointers, allocatables, arrays, coarrays, or
 // function results.  They can be components of other derived types.
 // Although the F'2018 Standard never prohibits multiple image-selectors
-// in the same data-ref or designator, nor the presence of an image-selector
-// after a part-ref with rank, the constraints on the derived types that
-// would have be involved make it impossible to declare an object that
-// could be referenced in these ways.
+// per se in the same data-ref or designator, nor the presence of an
+// image-selector after a part-ref with rank, the constraints on the
+// derived types that would have be involved make it impossible to declare
+// an object that could be referenced in these ways (esp. C748 & C825).
 // C930 precludes having both TEAM= and TEAM_NUMBER=.
 // TODO C931 prohibits the use of a coindexed object as a stat-variable.
 class CoarrayRef {
 public:
-  struct BasePartRef {
-    explicit BasePartRef(const Symbol &s) : symbol{&s} {}
-    BasePartRef(const Symbol &s, std::vector<Expr<SubscriptInteger>> &&ss)
-      : symbol{&s}, subscript{std::move(ss)} {}
-    CLASS_BOILERPLATE(BasePartRef)
-    bool operator==(const BasePartRef &) const;
-    const Symbol *symbol;
-    std::vector<Expr<SubscriptInteger>> subscript;
-  };
-  using BaseDataRef = std::vector<BasePartRef>;
-
   CLASS_BOILERPLATE(CoarrayRef)
-  CoarrayRef(BaseDataRef &&, std::vector<Expr<SubscriptInteger>> &&);
+  CoarrayRef(std::vector<const Symbol *> &&, std::vector<Subscript> &&,
+      std::vector<Expr<SubscriptInteger>> &&);
 
-  const BaseDataRef &baseDataRef() const { return baseDataRef_; }
-  BaseDataRef &baseDataRef() { return baseDataRef_; }
+  const std::vector<const Symbol *> &base() const { return base_; }
+  std::vector<const Symbol *> &base() { return base_; }
+  const std::vector<Subscript> &subscript() const { return subscript_; }
+  std::vector<Subscript> &subscript() { return subscript_; }
   const std::vector<Expr<SubscriptInteger>> &cosubscript() const {
     return cosubscript_;
   }
@@ -242,7 +234,7 @@ public:
   bool teamIsTeamNumber() const { return teamIsTeamNumber_; }
   CoarrayRef &set_team(Expr<SomeInteger> &&, bool isTeamNumber = false);
 
-  int Rank() const { return 0; }
+  int Rank() const;
   const Symbol &GetFirstSymbol() const;
   const Symbol &GetLastSymbol() const;
   Expr<SubscriptInteger> LEN() const;
@@ -250,7 +242,8 @@ public:
   std::ostream &AsFortran(std::ostream &) const;
 
 private:
-  BaseDataRef baseDataRef_;
+  std::vector<const Symbol *> base_;
+  std::vector<Subscript> subscript_;
   std::vector<Expr<SubscriptInteger>> cosubscript_;
   std::optional<common::CopyableIndirection<Expr<SomeInteger>>> stat_, team_;
   bool teamIsTeamNumber_{false};  // false: TEAM=, true: TEAM_NUMBER=