[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:
parent
2105abf176
commit
52d46695fc
|
@ -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); }
|
||||
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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});
|
||||
|
|
|
@ -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_);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue