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());
}
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)));
}
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 = ',';
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()) {
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);
}
}
}
-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 {
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) {
}
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{}
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_;
}
// 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_;
}
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;
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=