[flang] more data hiding

Original-commit: flang-compiler/f18@2dc0d046e3
Reviewed-on: https://github.com/flang-compiler/f18/pull/144
Tree-same-pre-rewrite: false
This commit is contained in:
peter klausler 2018-07-12 16:07:43 -07:00
parent 7dbc09357e
commit 006642f98a
2 changed files with 133 additions and 86 deletions

View File

@ -21,20 +21,101 @@
namespace Fortran::evaluate {
// Constructors, accessors, mutators
Triplet::Triplet(std::optional<SubscriptIntegerExpr> &&l,
std::optional<SubscriptIntegerExpr> &&u,
std::optional<SubscriptIntegerExpr> &&s) {
if (l.has_value()) {
lower = IndirectSubscriptIntegerExpr::Make(std::move(*l));
lower_ = IndirectSubscriptIntegerExpr::Make(std::move(*l));
}
if (u.has_value()) {
upper = IndirectSubscriptIntegerExpr::Make(std::move(*u));
upper_ = IndirectSubscriptIntegerExpr::Make(std::move(*u));
}
if (s.has_value()) {
stride = IndirectSubscriptIntegerExpr::Make(std::move(*s));
stride_ = IndirectSubscriptIntegerExpr::Make(std::move(*s));
}
}
std::optional<SubscriptIntegerExpr> Triplet::lower() const {
if (lower_) {
return {**lower_};
}
return {};
}
std::optional<SubscriptIntegerExpr> Triplet::upper() const {
if (upper_) {
return {**upper_};
}
return {};
}
std::optional<SubscriptIntegerExpr> Triplet::stride() const {
if (stride_) {
return {**stride_};
}
return {};
}
CoarrayRef::CoarrayRef(std::vector<const Symbol *> &&c,
std::vector<SubscriptIntegerExpr> &&ss,
std::vector<SubscriptIntegerExpr> &&css)
: base_(std::move(c)), subscript_(std::move(ss)), cosubscript_(std::move(css)) {
CHECK(!base_.empty());
}
CoarrayRef &CoarrayRef::setStat(Variable &&v) {
stat_ = CopyableIndirection<Variable>::Make(std::move(v));
return *this;
}
CoarrayRef &CoarrayRef::setTeam(Variable &&v, bool isTeamNumber) {
team_ = CopyableIndirection<Variable>::Make(std::move(v));
teamIsTeamNumber_ = isTeamNumber;
return *this;
}
Substring::Substring(DataRef &&d, std::optional<SubscriptIntegerExpr> &&f,
std::optional<SubscriptIntegerExpr> &&l)
: u{std::move(d)} {
if (f.has_value()) {
first = IndirectSubscriptIntegerExpr::Make(std::move(*f));
}
if (l.has_value()) {
last = IndirectSubscriptIntegerExpr::Make(std::move(*l));
}
}
Substring::Substring(std::string &&s, std::optional<SubscriptIntegerExpr> &&f,
std::optional<SubscriptIntegerExpr> &&l)
: u{std::move(s)} {
if (f.has_value()) {
first = IndirectSubscriptIntegerExpr::Make(std::move(*f));
}
if (l.has_value()) {
last = IndirectSubscriptIntegerExpr::Make(std::move(*l));
}
}
SubscriptIntegerExpr Substring::First() const {
if (first.has_value()) {
return **first;
}
return {1};
}
SubscriptIntegerExpr Substring::Last() const {
if (last.has_value()) {
return **last;
}
return std::visit(common::visitors{[](const std::string &s) {
return SubscriptIntegerExpr{s.size()};
},
[](const DataRef &x) { return x.LEN(); }},
u);
}
// Variable dumping
template<typename A> std::ostream &Emit(std::ostream &o, const A &x) {
@ -98,20 +179,20 @@ std::ostream &Component::Dump(std::ostream &o) const {
}
std::ostream &Triplet::Dump(std::ostream &o) const {
Emit(o, lower) << ':';
Emit(o, upper);
if (stride) {
Emit(o << ':', stride);
Emit(o, lower_) << ':';
Emit(o, upper_);
if (stride_) {
Emit(o << ':', stride_);
}
return o;
}
std::ostream &Subscript::Dump(std::ostream &o) const { return Emit(o, u); }
std::ostream &Subscript::Dump(std::ostream &o) const { return Emit(o, u_); }
std::ostream &ArrayRef::Dump(std::ostream &o) const {
Emit(o, u);
Emit(o, u_);
char separator{'('};
for (const Subscript &ss : subscript) {
for (const Subscript &ss : subscript_) {
ss.Dump(o << separator);
separator = ',';
}
@ -119,11 +200,11 @@ std::ostream &ArrayRef::Dump(std::ostream &o) const {
}
std::ostream &CoarrayRef::Dump(std::ostream &o) const {
for (const Symbol *sym : base) {
for (const Symbol *sym : base_) {
Emit(o, *sym);
}
char separator{'('};
for (const auto &ss : subscript) {
for (const auto &ss : subscript_) {
Emit(o << separator, ss);
separator = ',';
}
@ -131,16 +212,16 @@ std::ostream &CoarrayRef::Dump(std::ostream &o) const {
o << ')';
}
separator = '[';
for (const auto &css : cosubscript) {
for (const auto &css : cosubscript_) {
Emit(o << separator, css);
separator = ',';
}
if (stat.has_value()) {
Emit(o << separator, stat, "STAT=");
if (stat_.has_value()) {
Emit(o << separator, stat_, "STAT=");
separator = ',';
}
if (team.has_value()) {
Emit(o << separator, team, teamIsTeamNumber ? "TEAM_NUMBER=" : "TEAM=");
if (team_.has_value()) {
Emit(o << separator, team_, teamIsTeamNumber_ ? "TEAM_NUMBER=" : "TEAM=");
}
return o << ']';
}
@ -190,53 +271,6 @@ std::ostream &Label::Dump(std::ostream &o) const {
return o << '*' << std::dec << label;
}
CoarrayRef::CoarrayRef(std::vector<const Symbol *> &&c,
std::vector<SubscriptIntegerExpr> &&ss,
std::vector<SubscriptIntegerExpr> &&css)
: base(std::move(c)), subscript(std::move(ss)), cosubscript(std::move(css)) {
CHECK(!base.empty());
}
Substring::Substring(DataRef &&d, std::optional<SubscriptIntegerExpr> &&f,
std::optional<SubscriptIntegerExpr> &&l)
: u{std::move(d)} {
if (f.has_value()) {
first = IndirectSubscriptIntegerExpr::Make(std::move(*f));
}
if (l.has_value()) {
last = IndirectSubscriptIntegerExpr::Make(std::move(*l));
}
}
Substring::Substring(std::string &&s, std::optional<SubscriptIntegerExpr> &&f,
std::optional<SubscriptIntegerExpr> &&l)
: u{std::move(s)} {
if (f.has_value()) {
first = IndirectSubscriptIntegerExpr::Make(std::move(*f));
}
if (l.has_value()) {
last = IndirectSubscriptIntegerExpr::Make(std::move(*l));
}
}
SubscriptIntegerExpr Substring::First() const {
if (first.has_value()) {
return **first;
}
return {1};
}
SubscriptIntegerExpr Substring::Last() const {
if (last.has_value()) {
return **last;
}
return std::visit(common::visitors{[](const std::string &s) {
return SubscriptIntegerExpr{s.size()};
},
[](const DataRef &x) { return x.LEN(); }},
u);
}
// LEN()
static SubscriptIntegerExpr SymbolLEN(const Symbol &sym) {
return SubscriptIntegerExpr{0}; // TODO
@ -246,9 +280,9 @@ SubscriptIntegerExpr ArrayRef::LEN() const {
return std::visit(
common::visitors{[](const Symbol *s) { return SymbolLEN(*s); },
[](const Component &x) { return x.LEN(); }},
u);
u_);
}
SubscriptIntegerExpr CoarrayRef::LEN() const { return SymbolLEN(*base.back()); }
SubscriptIntegerExpr CoarrayRef::LEN() const { return SymbolLEN(*base_.back()); }
SubscriptIntegerExpr DataRef::LEN() const {
return std::visit(
common::visitors{[](const Symbol *s) { return SymbolLEN(*s); },

View File

@ -66,27 +66,32 @@ private:
const Symbol *symbol_;
};
// TODO pmk continue data hiding from here...
// R921 subscript-triplet
struct Triplet {
class Triplet {
public:
CLASS_BOILERPLATE(Triplet)
Triplet(std::optional<SubscriptIntegerExpr> &&,
std::optional<SubscriptIntegerExpr> &&,
std::optional<SubscriptIntegerExpr> &&);
std::optional<IndirectSubscriptIntegerExpr> lower, upper, stride;
std::optional<SubscriptIntegerExpr> lower() const;
std::optional<SubscriptIntegerExpr> upper() const;
std::optional<SubscriptIntegerExpr> stride() const;
private:
std::optional<IndirectSubscriptIntegerExpr> lower_, upper_, stride_;
};
// R919 subscript when rank 0, R923 vector-subscript when rank 1
struct Subscript {
class Subscript {
public:
CLASS_BOILERPLATE(Subscript)
explicit Subscript(const SubscriptIntegerExpr &s)
: u{IndirectSubscriptIntegerExpr::Make(s)} {}
: u_{IndirectSubscriptIntegerExpr::Make(s)} {}
explicit Subscript(SubscriptIntegerExpr &&s)
: u{IndirectSubscriptIntegerExpr::Make(std::move(s))} {}
explicit Subscript(const Triplet &t) : u{t} {}
explicit Subscript(Triplet &&t) : u{std::move(t)} {}
std::variant<IndirectSubscriptIntegerExpr, Triplet> u;
: u_{IndirectSubscriptIntegerExpr::Make(std::move(s))} {}
explicit Subscript(const Triplet &t) : u_{t} {}
explicit Subscript(Triplet &&t) : u_{std::move(t)} {}
private:
std::variant<IndirectSubscriptIntegerExpr, Triplet> u_;
};
// R917 array-element, R918 array-section; however, the case of an
@ -94,15 +99,17 @@ struct Subscript {
// as a ComplexPart instead. C919 & C925 require that at most one set of
// subscripts have rank greater than 0, but that is not explicit in
// these types.
struct ArrayRef {
class ArrayRef {
public:
CLASS_BOILERPLATE(ArrayRef)
ArrayRef(const Symbol &n, std::vector<Subscript> &&ss)
: u{&n}, subscript(std::move(ss)) {}
: u_{&n}, subscript_(std::move(ss)) {}
ArrayRef(Component &&c, std::vector<Subscript> &&ss)
: u{std::move(c)}, subscript(std::move(ss)) {}
: u_{std::move(c)}, subscript_(std::move(ss)) {}
SubscriptIntegerExpr LEN() const;
std::variant<const Symbol *, Component> u;
std::vector<Subscript> subscript;
private:
std::variant<const Symbol *, Component> u_;
std::vector<Subscript> subscript_;
};
// R914 coindexed-named-object
@ -112,18 +119,24 @@ struct ArrayRef {
// function results. They can be components of other derived types.
// C930 precludes having both TEAM= and TEAM_NUMBER=.
// TODO C931 prohibits the use of a coindexed object as a stat-variable.
struct CoarrayRef {
class CoarrayRef {
public:
CLASS_BOILERPLATE(CoarrayRef)
CoarrayRef(std::vector<const Symbol *> &&,
std::vector<SubscriptIntegerExpr> &&,
std::vector<SubscriptIntegerExpr> &&); // TODO: stat & team?
CoarrayRef &setStat(Variable &&);
CoarrayRef &setTeam(Variable &&, bool isTeamNumber = false);
SubscriptIntegerExpr LEN() const;
std::vector<const Symbol *> base;
std::vector<SubscriptIntegerExpr> subscript, cosubscript;
std::optional<CopyableIndirection<Variable>> stat, team;
bool teamIsTeamNumber{false}; // false: TEAM=, true: TEAM_NUMBER=
private:
std::vector<const Symbol *> base_;
std::vector<SubscriptIntegerExpr> subscript_, cosubscript_;
std::optional<CopyableIndirection<Variable>> stat_, team_;
bool teamIsTeamNumber_{false}; // false: TEAM=, true: TEAM_NUMBER=
};
// TODO pmk continue with data hiding from here
// R911 data-ref is defined syntactically as a series of part-refs, which
// would be far too expressive if the constraints were ignored. Here, the
// possible outcomes are spelled out. Note that a data-ref cannot include