[flang] Finish data hiding in variable.h.

Original-commit: flang-compiler/f18@5979330322
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:58:21 -07:00
parent 006642f98a
commit 05f0e2f7ec
4 changed files with 123 additions and 81 deletions

View File

@ -81,7 +81,9 @@ std::ostream &Expr<Category::Integer, KIND>::Dump(std::ostream &o) const {
[&](const Power &p) { p.Dump(o, "**"); },
[&](const Max &m) { m.Dump(o, ",", "MAX("); },
[&](const Min &m) { m.Dump(o, ",", "MIN("); },
[&](const auto &convert) { DumpExprWithType(o, convert.operand().u); }},
[&](const auto &convert) {
DumpExprWithType(o, convert.operand().u);
}},
u_);
return o;
}
@ -105,7 +107,9 @@ std::ostream &Expr<Category::Real, KIND>::Dump(std::ostream &o) const {
[&](const Min &m) { m.Dump(o, ",", "MIN("); },
[&](const RealPart &z) { z.Dump(o, "REAL("); },
[&](const AIMAG &p) { p.Dump(o, "AIMAG("); },
[&](const auto &convert) { DumpExprWithType(o, convert.operand().u); }},
[&](const auto &convert) {
DumpExprWithType(o, convert.operand().u);
}},
u_);
return o;
}
@ -182,7 +186,7 @@ SubscriptIntegerExpr Expr<Category::Character, KIND>::LEN() const {
[](const CopyableIndirection<DataRef> &dr) { return dr->LEN(); },
[](const CopyableIndirection<Substring> &ss) { return ss->LEN(); },
[](const CopyableIndirection<FunctionRef> &fr) {
return fr->proc.LEN();
return fr->proc().LEN();
}},
u_);
}

View File

@ -50,6 +50,7 @@ public:
const A &operand() const { return *operand_; }
A &operand() { return *operand_; }
std::ostream &Dump(std::ostream &, const char *opr) const;
private:
CopyableIndirection<A> operand_;
};
@ -69,6 +70,7 @@ public:
B &right() { return *right_; }
std::ostream &Dump(
std::ostream &, const char *opr, const char *before = "(") const;
private:
CopyableIndirection<A> left_;
CopyableIndirection<B> right_;

View File

@ -61,7 +61,8 @@ std::optional<SubscriptIntegerExpr> Triplet::stride() const {
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)) {
: base_(std::move(c)), subscript_(std::move(ss)),
cosubscript_(std::move(css)) {
CHECK(!base_.empty());
}
@ -78,42 +79,42 @@ CoarrayRef &CoarrayRef::setTeam(Variable &&v, bool isTeamNumber) {
Substring::Substring(DataRef &&d, std::optional<SubscriptIntegerExpr> &&f,
std::optional<SubscriptIntegerExpr> &&l)
: u{std::move(d)} {
: u_{std::move(d)} {
if (f.has_value()) {
first = IndirectSubscriptIntegerExpr::Make(std::move(*f));
first_ = IndirectSubscriptIntegerExpr::Make(std::move(*f));
}
if (l.has_value()) {
last = IndirectSubscriptIntegerExpr::Make(std::move(*l));
last_ = IndirectSubscriptIntegerExpr::Make(std::move(*l));
}
}
Substring::Substring(std::string &&s, std::optional<SubscriptIntegerExpr> &&f,
std::optional<SubscriptIntegerExpr> &&l)
: u{std::move(s)} {
: u_{std::move(s)} {
if (f.has_value()) {
first = IndirectSubscriptIntegerExpr::Make(std::move(*f));
first_ = IndirectSubscriptIntegerExpr::Make(std::move(*f));
}
if (l.has_value()) {
last = IndirectSubscriptIntegerExpr::Make(std::move(*l));
last_ = IndirectSubscriptIntegerExpr::Make(std::move(*l));
}
}
SubscriptIntegerExpr Substring::First() const {
if (first.has_value()) {
return **first;
SubscriptIntegerExpr Substring::first() const {
if (first_.has_value()) {
return **first_;
}
return {1};
}
SubscriptIntegerExpr Substring::Last() const {
if (last.has_value()) {
return **last;
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);
u_);
}
// Variable dumping
@ -226,29 +227,29 @@ std::ostream &CoarrayRef::Dump(std::ostream &o) const {
return o << ']';
}
std::ostream &DataRef::Dump(std::ostream &o) const { return Emit(o, u); }
std::ostream &DataRef::Dump(std::ostream &o) const { return Emit(o, u_); }
std::ostream &Substring::Dump(std::ostream &o) const {
Emit(o, u) << '(';
Emit(o, first) << ':';
return Emit(o, last);
Emit(o, u_) << '(';
Emit(o, first_) << ':';
return Emit(o, last_);
}
std::ostream &ComplexPart::Dump(std::ostream &o) const {
return complex.Dump(o) << '%' << EnumToString(part);
return complex_.Dump(o) << '%' << EnumToString(part_);
}
std::ostream &Designator::Dump(std::ostream &o) const { return Emit(o, u); }
std::ostream &Designator::Dump(std::ostream &o) const { return Emit(o, u_); }
std::ostream &ProcedureDesignator::Dump(std::ostream &o) const {
return Emit(o, u);
return Emit(o, u_);
}
template<typename ARG>
std::ostream &ProcedureRef<ARG>::Dump(std::ostream &o) const {
Emit(o, proc);
Emit(o, proc_);
char separator{'('};
for (const auto &arg : argument) {
for (const auto &arg : argument_) {
Emit(o << separator, arg);
separator = ',';
}
@ -258,13 +259,13 @@ std::ostream &ProcedureRef<ARG>::Dump(std::ostream &o) const {
return o << ')';
}
std::ostream &Variable::Dump(std::ostream &o) const { return Emit(o, u); }
std::ostream &Variable::Dump(std::ostream &o) const { return Emit(o, u_); }
std::ostream &ActualFunctionArg::Dump(std::ostream &o) const {
return Emit(o, u);
return Emit(o, u_);
}
std::ostream &ActualSubroutineArg::Dump(std::ostream &o) const {
return Emit(o, u);
return Emit(o, u_);
}
std::ostream &Label::Dump(std::ostream &o) const {
@ -282,16 +283,18 @@ SubscriptIntegerExpr ArrayRef::LEN() const {
[](const Component &x) { return x.LEN(); }},
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); },
[](const auto &x) { return x.LEN(); }},
u);
u_);
}
SubscriptIntegerExpr Substring::LEN() const {
return SubscriptIntegerExpr::Max{
SubscriptIntegerExpr{0}, Last() - First() + SubscriptIntegerExpr{1}};
SubscriptIntegerExpr{0}, last() - first() + SubscriptIntegerExpr{1}};
}
SubscriptIntegerExpr ProcedureDesignator::LEN() const {
return std::visit(
@ -301,7 +304,7 @@ SubscriptIntegerExpr ProcedureDesignator::LEN() const {
CRASH_NO_CASE;
return SubscriptIntegerExpr{0};
}},
u);
u_);
}
} // namespace Fortran::evaluate

View File

@ -36,9 +36,9 @@ namespace Fortran::evaluate {
using semantics::Symbol;
// Forward declarations
struct DataRef;
struct Variable;
struct ActualFunctionArg;
class DataRef;
class Variable;
class ActualFunctionArg;
// Subscript and cosubscript expressions are of a kind that matches the
// address size, at least at the top level.
@ -61,6 +61,7 @@ public:
DataRef &base() { return *base_; }
const Symbol &symbol() const { return *symbol_; }
SubscriptIntegerExpr LEN() const;
private:
CopyableIndirection<DataRef> base_;
const Symbol *symbol_;
@ -76,6 +77,7 @@ public:
std::optional<SubscriptIntegerExpr> lower() const;
std::optional<SubscriptIntegerExpr> upper() const;
std::optional<SubscriptIntegerExpr> stride() const;
private:
std::optional<IndirectSubscriptIntegerExpr> lower_, upper_, stride_;
};
@ -90,6 +92,7 @@ public:
: 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_;
};
@ -107,6 +110,7 @@ public:
ArrayRef(Component &&c, std::vector<Subscript> &&ss)
: u_{std::move(c)}, subscript_(std::move(ss)) {}
SubscriptIntegerExpr LEN() const;
private:
std::variant<const Symbol *, Component> u_;
std::vector<Subscript> subscript_;
@ -128,6 +132,7 @@ public:
CoarrayRef &setStat(Variable &&);
CoarrayRef &setTeam(Variable &&, bool isTeamNumber = false);
SubscriptIntegerExpr LEN() const;
private:
std::vector<const Symbol *> base_;
std::vector<SubscriptIntegerExpr> subscript_, cosubscript_;
@ -135,96 +140,121 @@ private:
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
// a terminal substring range or complex component designator; use
// R901 designator for that.
struct DataRef {
class DataRef {
public:
CLASS_BOILERPLATE(DataRef)
explicit DataRef(const Symbol &n) : u{&n} {}
explicit DataRef(Component &&c) : u{std::move(c)} {}
explicit DataRef(ArrayRef &&a) : u{std::move(a)} {}
explicit DataRef(CoarrayRef &&a) : u{std::move(a)} {}
explicit DataRef(const Symbol &n) : u_{&n} {}
explicit DataRef(Component &&c) : u_{std::move(c)} {}
explicit DataRef(ArrayRef &&a) : u_{std::move(a)} {}
explicit DataRef(CoarrayRef &&a) : u_{std::move(a)} {}
SubscriptIntegerExpr LEN() const;
std::variant<const Symbol *, Component, ArrayRef, CoarrayRef> u;
private:
std::variant<const Symbol *, Component, ArrayRef, CoarrayRef> u_;
};
// R908 substring, R909 parent-string, R910 substring-range.
// The base object of a substring can be a literal.
// In the F2018 standard, substrings of array sections are parsed as
// variants of sections instead.
struct Substring {
class Substring {
public:
CLASS_BOILERPLATE(Substring)
Substring(DataRef &&, std::optional<SubscriptIntegerExpr> &&,
std::optional<SubscriptIntegerExpr> &&);
Substring(std::string &&, std::optional<SubscriptIntegerExpr> &&,
std::optional<SubscriptIntegerExpr> &&);
SubscriptIntegerExpr First() const;
SubscriptIntegerExpr Last() const;
SubscriptIntegerExpr first() const;
SubscriptIntegerExpr last() const;
SubscriptIntegerExpr LEN() const;
std::variant<DataRef, std::string> u;
std::optional<IndirectSubscriptIntegerExpr> first, last;
private:
std::variant<DataRef, std::string> u_;
std::optional<IndirectSubscriptIntegerExpr> first_, last_;
};
// R915 complex-part-designator
// In the F2018 standard, complex parts of array sections are parsed as
// variants of sections instead.
struct ComplexPart {
class ComplexPart {
public:
ENUM_CLASS(Part, RE, IM)
CLASS_BOILERPLATE(ComplexPart)
ComplexPart(DataRef &&z, Part p) : complex{std::move(z)}, part{p} {}
DataRef complex;
Part part;
ComplexPart(DataRef &&z, Part p) : complex_{std::move(z)}, part_{p} {}
const DataRef &complex() const { return complex_; }
Part part() const { return part_; }
private:
DataRef complex_;
Part part_;
};
// R901 designator is the most general data reference object, apart from
// calls to pointer-valued functions.
struct Designator {
class Designator {
public:
CLASS_BOILERPLATE(Designator)
explicit Designator(DataRef &&d) : u{std::move(d)} {}
explicit Designator(Substring &&s) : u{std::move(s)} {}
explicit Designator(ComplexPart &&c) : u{std::move(c)} {}
std::variant<DataRef, Substring, ComplexPart> u;
explicit Designator(DataRef &&d) : u_{std::move(d)} {}
explicit Designator(Substring &&s) : u_{std::move(s)} {}
explicit Designator(ComplexPart &&c) : u_{std::move(c)} {}
private:
std::variant<DataRef, Substring, ComplexPart> u_;
};
struct ProcedureDesignator {
class ProcedureDesignator {
public:
CLASS_BOILERPLATE(ProcedureDesignator)
explicit ProcedureDesignator(IntrinsicProcedure p) : u{p} {}
explicit ProcedureDesignator(const Symbol &n) : u{&n} {}
explicit ProcedureDesignator(const Component &c) : u{c} {}
explicit ProcedureDesignator(Component &&c) : u{std::move(c)} {}
explicit ProcedureDesignator(IntrinsicProcedure p) : u_{p} {}
explicit ProcedureDesignator(const Symbol &n) : u_{&n} {}
explicit ProcedureDesignator(const Component &c) : u_{c} {}
explicit ProcedureDesignator(Component &&c) : u_{std::move(c)} {}
SubscriptIntegerExpr LEN() const;
std::variant<IntrinsicProcedure, const Symbol *, Component> u;
private:
std::variant<IntrinsicProcedure, const Symbol *, Component> u_;
};
template<typename ARG> struct ProcedureRef {
template<typename ARG> class ProcedureRef {
public:
using ArgumentType = CopyableIndirection<ARG>;
CLASS_BOILERPLATE(ProcedureRef)
ProcedureRef(ProcedureDesignator &&p, std::vector<ArgumentType> &&a)
: proc{std::move(p)}, argument(std::move(a)) {}
ProcedureDesignator proc;
std::vector<ArgumentType> argument;
: proc_{std::move(p)}, argument_(std::move(a)) {}
const ProcedureDesignator &proc() const { return proc_; }
const std::vector<ArgumentType> &argument() const { return argument_; }
private:
ProcedureDesignator proc_;
std::vector<ArgumentType> argument_;
};
using FunctionRef = ProcedureRef<ActualFunctionArg>;
struct Variable {
class Variable {
public:
CLASS_BOILERPLATE(Variable)
explicit Variable(Designator &&d) : u{std::move(d)} {}
explicit Variable(FunctionRef &&p) : u{std::move(p)} {}
std::variant<Designator, FunctionRef> u;
explicit Variable(Designator &&d) : u_{std::move(d)} {}
explicit Variable(FunctionRef &&p) : u_{std::move(p)} {}
private:
std::variant<Designator, FunctionRef> u_;
};
struct ActualFunctionArg {
class ActualFunctionArg {
public:
CLASS_BOILERPLATE(ActualFunctionArg)
explicit ActualFunctionArg(GenericExpr &&x) : u{std::move(x)} {}
explicit ActualFunctionArg(Variable &&x) : u{std::move(x)} {}
std::variant<CopyableIndirection<GenericExpr>, Variable> u;
explicit ActualFunctionArg(GenericExpr &&x) : u_{std::move(x)} {}
explicit ActualFunctionArg(Variable &&x) : u_{std::move(x)} {}
private:
std::variant<CopyableIndirection<GenericExpr>, Variable> u_;
};
struct Label { // TODO: this is a placeholder
@ -233,12 +263,15 @@ struct Label { // TODO: this is a placeholder
int label;
};
struct ActualSubroutineArg {
class ActualSubroutineArg {
public:
CLASS_BOILERPLATE(ActualSubroutineArg)
explicit ActualSubroutineArg(GenericExpr &&x) : u{std::move(x)} {}
explicit ActualSubroutineArg(Variable &&x) : u{std::move(x)} {}
explicit ActualSubroutineArg(const Label &l) : u{&l} {}
std::variant<CopyableIndirection<GenericExpr>, Variable, const Label *> u;
explicit ActualSubroutineArg(GenericExpr &&x) : u_{std::move(x)} {}
explicit ActualSubroutineArg(Variable &&x) : u_{std::move(x)} {}
explicit ActualSubroutineArg(const Label &l) : u_{&l} {}
private:
std::variant<CopyableIndirection<GenericExpr>, Variable, const Label *> u_;
};
using SubroutineRef = ProcedureRef<ActualSubroutineArg>;