From: peter klausler Date: Thu, 7 Mar 2019 00:15:20 +0000 (-0800) Subject: [flang] add descender.h X-Git-Tag: llvmorg-12-init~9537^2~1663 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=18e436afc4b380687df6cfb7261733fc04a19675;p=platform%2Fupstream%2Fllvm.git [flang] add descender.h Original-commit: flang-compiler/f18@cfc3082b7ae840168e891dcf25e0034a4193a3fd Reviewed-on: https://github.com/flang-compiler/f18/pull/316 --- diff --git a/flang/lib/evaluate/descender.h b/flang/lib/evaluate/descender.h new file mode 100644 index 0000000..4dea229 --- /dev/null +++ b/flang/lib/evaluate/descender.h @@ -0,0 +1,264 @@ +// Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef FORTRAN_EVALUATE_DESCENDER_H_ +#define FORTRAN_EVALUATE_DESCENDER_H_ + +// Helper friend class templates for Visitor::Visit() and Rewriter::Traverse(). + +#include "expression.h" + +namespace Fortran::evaluate { + +template class Descender { +public: + explicit Descender(VISITOR &v) : visitor_{v} {} + + // Default cases + template void Descend(const X &) {} + template void Descend(X &x) {} + + template void Descend(const X *p) { + if (p != nullptr) { + Visit(*p); + } + } + template void Descend(X *p) { + if (p != nullptr) { + Visit(*p); + } + } + + template void Descend(const std::optional &o) { + if (o.has_value()) { + Visit(*o); + } + } + template void Descend(std::optional &o) { + if (o.has_value()) { + Visit(*o); + } + } + + template void Descend(const CopyableIndirection &p) { + Visit(p.value()); + } + template void Descend(CopyableIndirection &p) { + Visit(p.value()); + } + + template void Descend(const std::variant &u) { + std::visit([&](const auto &x) { Visit(x); }, u); + } + template void Descend(std::variant &u) { + std::visit([&](auto &x) { Visit(x); }, u); + } + + template void Descend(const std::vector &xs) { + for (const auto &x : xs) { + Visit(x); + } + } + template void Descend(std::vector &xs) { + for (auto &x : xs) { + Visit(x); + } + } + + template void Descend(const Expr &expr) { Visit(expr.u); } + template void Descend(Expr &expr) { Visit(expr.u); } + + template + void Descend(const Operation &op) { + Visit(op.left()); + if constexpr (op.operands > 1) { + Visit(op.right()); + } + } + template + void Descend(Operation &op) { + Visit(op.left()); + if constexpr (op.operands > 1) { + Visit(op.right()); + } + } + + template void Descend(const ImpliedDo &ido) { + Visit(ido.lower()); + Visit(ido.upper()); + Visit(ido.stride()); + Visit(ido.values()); + } + template void Descend(ImpliedDo &ido) { + Visit(ido.lower()); + Visit(ido.upper()); + Visit(ido.stride()); + Visit(ido.values()); + } + + template void Descend(const ArrayConstructorValue &av) { + Visit(av.u); + } + template void Descend(ArrayConstructorValue &av) { + Visit(av.u); + } + + template void Descend(const ArrayConstructorValues &avs) { + Visit(avs.values()); + } + template void Descend(ArrayConstructorValues &avs) { + Visit(avs.values()); + } + + template + void Descend( + const ArrayConstructor> &ac) { + const ArrayConstructorValues> &base{ac}; + Visit(base); + Visit(ac.LEN()); + } + template + void Descend(ArrayConstructor> &ac) { + ArrayConstructorValues> &base{ac}; + Visit(base); + Visit(ac.LEN()); + } + + void Descend(const semantics::ParamValue ¶m) { + Visit(param.GetExplicit()); + } + void Descend(semantics::ParamValue ¶m) { Visit(param.GetExplicit()); } + + void Descend(const semantics::DerivedTypeSpec &derived) { + for (const auto &pair : derived.parameters()) { + Visit(pair.second); + } + } + void Descend(semantics::DerivedTypeSpec &derived) { + for (const auto &pair : derived.parameters()) { + Visit(pair.second); + } + } + + void Descend(const StructureConstructor &sc) { + Visit(sc.derivedTypeSpec()); + for (const auto &pair : sc.values()) { + Visit(pair.second); + } + } + void Descend(StructureConstructor &sc) { + Visit(sc.derivedTypeSpec()); + for (const auto &pair : sc.values()) { + Visit(pair.second); + } + } + + void Descend(const BaseObject &object) { Visit(object.u); } + void Descend(BaseObject &object) { Visit(object.u); } + + void Descend(const Component &component) { + Visit(component.base()); + Visit(component.GetLastSymbol()); + } + void Descend(Component &component) { + Visit(component.base()); + Visit(component.GetLastSymbol()); + } + + template void Descend(const TypeParamInquiry &inq) { + Visit(inq.base()); + Visit(inq.parameter()); + } + template void Descend(TypeParamInquiry &inq) { + Visit(inq.base()); + Visit(inq.parameter()); + } + + void Descend(const Triplet &triplet) { + Visit(triplet.lower()); + Visit(triplet.upper()); + Visit(triplet.stride()); + } + void Descend(Triplet &triplet) { + Visit(triplet.lower()); + Visit(triplet.upper()); + Visit(triplet.stride()); + } + + void Descend(const Subscript &sscript) { Visit(sscript.u); } + void Descend(Subscript &sscript) { Visit(sscript.u); } + + void Descend(const ArrayRef &aref) { + Visit(aref.base()); + Visit(aref.subscript()); + } + void Descend(ArrayRef &aref) { + Visit(aref.base()); + Visit(aref.subscript()); + } + + void Descend(const CoarrayRef &caref) { + Visit(caref.base()); + Visit(caref.subscript()); + Visit(caref.cosubscript()); + Visit(caref.stat()); + Visit(caref.team()); + } + void Descend(CoarrayRef &caref) { + Visit(caref.base()); + Visit(caref.subscript()); + Visit(caref.cosubscript()); + Visit(caref.stat()); + Visit(caref.team()); + } + + void Descend(const DataRef &data) { Visit(data.u); } + void Descend(DataRef &data) { Visit(data.u); } + + void Descend(const ComplexPart &z) { Visit(z.complex()); } + void Descend(ComplexPart &z) { Visit(z.complex()); } + + template void Descend(const Designator &designator) { + Visit(designator.u); + } + template void Descend(Designator &designator) { + Visit(designator.u); + } + + template void Descend(const Variable &var) { Visit(var.u); } + template void Descend(Variable &var) { Visit(var.u); } + + void Descend(const ActualArgument &arg) { Visit(arg.value()); } + void Descend(ActualArgument &arg) { Visit(arg.value()); } + + void Descend(const ProcedureDesignator &p) { Visit(p.u); } + void Descend(ProcedureDesignator &p) { Visit(p.u); } + + void Descend(const ProcedureRef &call) { + Visit(call.proc()); + Visit(call.arguments()); + } + void Descend(ProcedureRef &call) { + Visit(call.proc()); + Visit(call.arguments()); + } + +private: + template void Visit(const T &x) { return visitor_.Visit(x); } + template void Visit(T &x) { x = visitor_.Traverse(std::move(x)); } + + VISITOR &visitor_; +}; +} +#endif // FORTRAN_EVALUATE_DESCENDER_H_