[flang] Handle remaining cases in expression traversal

Original-commit: flang-compiler/f18@5cb0de58d4
Reviewed-on: https://github.com/flang-compiler/f18/pull/449
Tree-same-pre-rewrite: false
This commit is contained in:
peter klausler 2019-05-07 16:19:45 -07:00
parent 2105abf176
commit 52d46695fc
5 changed files with 77 additions and 7 deletions

View file

@ -25,9 +25,19 @@ template<typename VISITOR> class Descender {
public:
explicit Descender(VISITOR &v) : visitor_{v} {}
// Default cases
template<typename X> void Descend(const X &) {}
template<typename X> void Descend(X &x) {}
// Base cases
void Descend(const semantics::Symbol &) {}
void Descend(semantics::Symbol &) {}
template<typename T> void Descend(const Constant<T> &) {}
template<typename T> void Descend(Constant<T> &) {}
void Descend(const std::shared_ptr<StaticDataObject> &) {}
void Descend(std::shared_ptr<StaticDataObject> &) {}
void Descend(const ImpliedDoIndex &) {}
void Descend(ImpliedDoIndex &) {}
void Descend(const BOZLiteralConstant &) {}
void Descend(BOZLiteralConstant &) {}
void Descend(const NullPointer &) {}
void Descend(NullPointer &) {}
template<typename X> void Descend(const X *p) {
if (p != nullptr) {
@ -60,6 +70,19 @@ public:
Visit(p.value());
}
template<typename X, typename DELETER>
void Descend(const std::unique_ptr<X, DELETER> &p) {
if (p.get() != nullptr) {
Visit(*p);
}
}
template<typename X, typename DELETER>
void Descend(std::unique_ptr<X, DELETER> &p) {
if (p.get() != nullptr) {
Visit(*p);
}
}
template<typename... X> void Descend(const std::variant<X...> &u) {
std::visit([&](const auto &x) { Visit(x); }, u);
}
@ -78,6 +101,9 @@ public:
}
}
void Descend(const GenericExprWrapper &w) { Visit(w.v); }
void Descend(GenericExprWrapper &w) { Visit(w.v); }
template<typename T> void Descend(const Expr<T> &expr) { Visit(expr.u); }
template<typename T> void Descend(Expr<T> &expr) { Visit(expr.u); }
@ -96,6 +122,9 @@ public:
}
}
void Descend(const Relational<SomeType> &r) { Visit(r.u); }
void Descend(Relational<SomeType> &r) { Visit(r.u); }
template<typename R> void Descend(const ImpliedDo<R> &ido) {
Visit(ido.lower());
Visit(ido.upper());
@ -191,6 +220,9 @@ public:
Visit(inq.parameter());
}
void Descend(const DescriptorInquiry &inq) { Visit(inq.base()); }
void Descend(DescriptorInquiry &inq) { Visit(inq.base()); }
void Descend(const Triplet &triplet) {
Visit(triplet.lower());
Visit(triplet.upper());
@ -235,6 +267,17 @@ public:
void Descend(const ComplexPart &z) { Visit(z.complex()); }
void Descend(ComplexPart &z) { Visit(z.complex()); }
void Descend(const Substring &ss) {
Visit(ss.parent());
Visit(ss.lower());
Visit(ss.upper());
}
void Descend(Substring &ss) {
Visit(ss.parent());
Visit(ss.lower());
Visit(ss.upper());
}
template<typename T> void Descend(const Designator<T> &designator) {
Visit(designator.u);
}
@ -262,6 +305,9 @@ public:
}
}
void Descend(const SpecificIntrinsic &si) {}
void Descend(SpecificIntrinsic &si) {}
void Descend(const ProcedureDesignator &p) { Visit(p.u); }
void Descend(ProcedureDesignator &p) { Visit(p.u); }

View file

@ -638,10 +638,10 @@ FOR_EACH_CHARACTER_KIND(extern template class Expr, )
// addition operator. Character relations must have the same kind.
// There are no relations between LOGICAL values.
template<typename A>
struct Relational : public Operation<Relational<A>, LogicalResult, A, A> {
template<typename T>
struct Relational : public Operation<Relational<T>, LogicalResult, T, T> {
using Result = LogicalResult;
using Base = Operation<Relational, LogicalResult, A, A>;
using Base = Operation<Relational, LogicalResult, T, T>;
using Operand = typename Base::template Operand<0>;
static_assert(Operand::category == TypeCategory::Integer ||
Operand::category == TypeCategory::Real ||

View file

@ -129,6 +129,14 @@ Expr<SubscriptInteger> Substring::lower() const {
}
}
Expr<SubscriptInteger> *Substring::lower() {
if (lower_.has_value()) {
return &lower_.value().value();
} else {
return nullptr;
}
}
Expr<SubscriptInteger> Substring::upper() const {
if (upper_.has_value()) {
return upper_.value().value();
@ -144,6 +152,14 @@ Expr<SubscriptInteger> Substring::upper() const {
}
}
Expr<SubscriptInteger> *Substring::upper() {
if (upper_.has_value()) {
return &upper_.value().value();
} else {
return nullptr;
}
}
std::optional<Expr<SomeCharacter>> Substring::Fold(FoldingContext &context) {
if (!lower_.has_value()) {
lower_ = AsExpr(Constant<SubscriptInteger>{1});

View file

@ -273,6 +273,8 @@ struct DataRef {
// In the F2018 standard, substrings of array sections are parsed as
// variants of sections instead.
class Substring {
using Parent = std::variant<DataRef, StaticDataObject::Pointer>;
public:
CLASS_BOILERPLATE(Substring)
Substring(DataRef &&parent, std::optional<Expr<SubscriptInteger>> &&lower,
@ -288,7 +290,12 @@ public:
}
Expr<SubscriptInteger> lower() const;
Expr<SubscriptInteger> *lower();
Expr<SubscriptInteger> upper() const;
Expr<SubscriptInteger> *upper();
const Parent &parent() const { return parent_; }
Parent &parent() { return parent_; }
int Rank() const;
template<typename A> const A *GetParentIf() const {
return std::get_if<A>(&parent_);

View file

@ -339,7 +339,8 @@ static CS GatherReferencesFromExpression(const parser::Expr &expression) {
explicit CollectSymbols(int) {}
void Handle(const Symbol *symbol) { result().push_back(symbol); }
};
return evaluate::Visitor<CollectSymbols>{0}.Traverse(*expression.typedExpr);
return evaluate::Visitor<GRFECollectSymbols>{0}.Traverse(
expression.typedExpr->v);
} else {
GatherSymbols gatherSymbols;
parser::Walk(expression, gatherSymbols);