[flang-commits] [flang] cd03e96 - [flang] Add & use a better visit() (take 2)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Sat Apr 16 16:01:03 PDT 2022
Author: Peter Klausler
Date: 2022-04-16T16:00:48-07:00
New Revision: cd03e96f00a8ab2489ae5af79375de2207f4e0ab
URL: https://github.com/llvm/llvm-project/commit/cd03e96f00a8ab2489ae5af79375de2207f4e0ab
DIFF: https://github.com/llvm/llvm-project/commit/cd03e96f00a8ab2489ae5af79375de2207f4e0ab.diff
LOG: [flang] Add & use a better visit() (take 2)
Adds flang/include/flang/Common/log2-visit.h, which defines
a Fortran::common::visit() template function that is a drop-in
replacement for std::visit(). Modifies most use sites in
the front-end and runtime to use common::visit().
The C++ standard mandates that std::visit() have O(1) execution
time, which forces implementations to build dispatch tables.
This new common::visit() is O(log2 N) in the number of alternatives
in a variant<>, but that N tends to be small and so this change
produces a fairly significant improvement in compiler build
memory requirements, a 5-10% improvement in compiler build time,
and a small improvement in compiler execution time.
Building with -DFLANG_USE_STD_VISIT causes common::visit()
to be an alias for std::visit().
Calls to common::visit() with multiple variant arguments
are referred to std::visit(), pending further work.
This change is enabled only for GCC builds with GCC >= 9;
an earlier attempt (D122441) ran into bugs in some versions of
clang and was reverted rather than simply disabled; and it is
not well tested with MSVC. In non-GCC and older GCC builds,
common::visit() is simply an alias for std::visit().
Added:
flang/include/flang/Common/visit.h
Modified:
flang/include/flang/Common/idioms.h
flang/include/flang/Common/template.h
flang/include/flang/Common/unwrap.h
flang/include/flang/Evaluate/expression.h
flang/include/flang/Evaluate/fold-designator.h
flang/include/flang/Evaluate/initial-image.h
flang/include/flang/Evaluate/shape.h
flang/include/flang/Evaluate/tools.h
flang/include/flang/Evaluate/traverse.h
flang/include/flang/Parser/parse-tree-visitor.h
flang/include/flang/Parser/tools.h
flang/include/flang/Semantics/expression.h
flang/include/flang/Semantics/symbol.h
flang/include/flang/Semantics/tools.h
flang/lib/Evaluate/call.cpp
flang/lib/Evaluate/characteristics.cpp
flang/lib/Evaluate/check-expression.cpp
flang/lib/Evaluate/expression.cpp
flang/lib/Evaluate/fold-designator.cpp
flang/lib/Evaluate/fold-implementation.h
flang/lib/Evaluate/fold-integer.cpp
flang/lib/Evaluate/fold-logical.cpp
flang/lib/Evaluate/fold-real.cpp
flang/lib/Evaluate/fold.cpp
flang/lib/Evaluate/formatting.cpp
flang/lib/Evaluate/shape.cpp
flang/lib/Evaluate/tools.cpp
flang/lib/Evaluate/type.cpp
flang/lib/Evaluate/variable.cpp
flang/lib/Parser/message.cpp
flang/lib/Parser/parse-tree.cpp
flang/lib/Parser/provenance.cpp
flang/lib/Parser/tools.cpp
flang/lib/Parser/unparse.cpp
flang/lib/Semantics/canonicalize-do.cpp
flang/lib/Semantics/check-allocate.cpp
flang/lib/Semantics/check-call.cpp
flang/lib/Semantics/check-case.cpp
flang/lib/Semantics/check-data.cpp
flang/lib/Semantics/check-deallocate.cpp
flang/lib/Semantics/check-declarations.cpp
flang/lib/Semantics/check-do-forall.cpp
flang/lib/Semantics/check-io.cpp
flang/lib/Semantics/check-nullify.cpp
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/check-select-rank.cpp
flang/lib/Semantics/check-select-type.cpp
flang/lib/Semantics/data-to-inits.cpp
flang/lib/Semantics/expression.cpp
flang/lib/Semantics/mod-file.cpp
flang/lib/Semantics/pointer-assignment.cpp
flang/lib/Semantics/program-tree.cpp
flang/lib/Semantics/resolve-directives.cpp
flang/lib/Semantics/resolve-names-utils.cpp
flang/lib/Semantics/resolve-names.cpp
flang/lib/Semantics/rewrite-parse-tree.cpp
flang/lib/Semantics/runtime-type-info.cpp
flang/lib/Semantics/symbol.cpp
flang/lib/Semantics/tools.cpp
flang/runtime/io-stmt.cpp
flang/runtime/io-stmt.h
Removed:
################################################################################
diff --git a/flang/include/flang/Common/idioms.h b/flang/include/flang/Common/idioms.h
index 84a8fd5be4cba..1a086162f1e2a 100644
--- a/flang/include/flang/Common/idioms.h
+++ b/flang/include/flang/Common/idioms.h
@@ -23,6 +23,7 @@
#error g++ >= 7.2 is required
#endif
+#include "visit.h"
#include "llvm/Support/Compiler.h"
#include <functional>
#include <list>
@@ -49,8 +50,8 @@ using namespace std::literals::string_literals;
namespace Fortran::common {
// Helper templates for combining a list of lambdas into an anonymous
-// struct for use with std::visit() on a std::variant<> sum type.
-// E.g.: std::visit(visitors{
+// struct for use with common::visit() on a std::variant<> sum type.
+// E.g.: common::visit(visitors{
// [&](const firstType &x) { ... },
// [&](const secondType &x) { ... },
// ...
diff --git a/flang/include/flang/Common/template.h b/flang/include/flang/Common/template.h
index f31b0afa97fb7..2a9958f74db38 100644
--- a/flang/include/flang/Common/template.h
+++ b/flang/include/flang/Common/template.h
@@ -118,14 +118,14 @@ template <typename A> const A *GetPtrFromOptional(const std::optional<A> &x) {
// Copy a value from one variant type to another. The types allowed in the
// source variant must all be allowed in the destination variant type.
template <typename TOV, typename FROMV> TOV CopyVariant(const FROMV &u) {
- return std::visit([](const auto &x) -> TOV { return {x}; }, u);
+ return common::visit([](const auto &x) -> TOV { return {x}; }, u);
}
// Move a value from one variant type to another. The types allowed in the
// source variant must all be allowed in the destination variant type.
template <typename TOV, typename FROMV>
common::IfNoLvalue<TOV, FROMV> MoveVariant(FROMV &&u) {
- return std::visit(
+ return common::visit(
[](auto &&x) -> TOV { return {std::move(x)}; }, std::move(u));
}
diff --git a/flang/include/flang/Common/unwrap.h b/flang/include/flang/Common/unwrap.h
index b6ea4a1546096..edb343d77b537 100644
--- a/flang/include/flang/Common/unwrap.h
+++ b/flang/include/flang/Common/unwrap.h
@@ -12,6 +12,7 @@
#include "indirection.h"
#include "reference-counted.h"
#include "reference.h"
+#include "visit.h"
#include <memory>
#include <optional>
#include <type_traits>
@@ -103,7 +104,7 @@ struct UnwrapperHelper {
template <typename A, typename... Bs>
static A *Unwrap(std::variant<Bs...> &u) {
- return std::visit(
+ return common::visit(
[](auto &x) -> A * {
using Ty = std::decay_t<decltype(Unwrap<A>(x))>;
if constexpr (!std::is_const_v<std::remove_pointer_t<Ty>> ||
@@ -117,7 +118,7 @@ struct UnwrapperHelper {
template <typename A, typename... Bs>
static auto Unwrap(const std::variant<Bs...> &u) -> std::add_const_t<A> * {
- return std::visit(
+ return common::visit(
[](const auto &x) -> std::add_const_t<A> * { return Unwrap<A>(x); }, u);
}
diff --git a/flang/include/flang/Common/visit.h b/flang/include/flang/Common/visit.h
new file mode 100644
index 0000000000000..d3136be3f6a1f
--- /dev/null
+++ b/flang/include/flang/Common/visit.h
@@ -0,0 +1,101 @@
+//===-- include/flang/Common/visit.h ----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// common::visit() is a drop-in replacement for std::visit() that reduces both
+// compiler build time and compiler execution time modestly, and reduces
+// compiler build memory requirements significantly (overall & maximum).
+// It does not require redefinition of std::variant<>.
+//
+// The C++ standard mandates that std::visit be O(1), but most variants are
+// small and O(logN) is faster in practice to compile and execute, avoiding
+// the need to build a dispatch table.
+//
+// Define FLANG_USE_STD_VISIT to avoid this code and make common::visit() an
+// alias for ::std::visit().
+//
+//
+// With GCC 9.3.0 on a Haswell x86 Ubuntu system, doing out-of-tree builds:
+// Before:
+// build:
+// 6948.53user 212.48system 27:32.92elapsed 433%CPU
+// (0avgtext+0avgdata 6429568maxresident)k
+// 36181912inputs+8943720outputs (3613684major+97908699minor)pagefaults 0swaps
+// execution of tests:
+// 205.99user 26.05system 1:08.87elapsed 336%CPU
+// (0avgtext+0avgdata 2671452maxresident)k
+// 244432inputs+355464outputs (422major+8746468minor)pagefaults 0swaps
+// After:
+// build:
+// 6651.91user 182.57system 25:15.73elapsed 450%CPU
+// (0avgtext+0avgdata 6209296maxresident)k
+// 17413480inputs+6376360outputs (1567210major+93068230minor)pagefaults 0swaps
+// execution of tests:
+// 201.42user 25.91system 1:04.68elapsed 351%CPU
+// (0avgtext+0avgdata 2661424maxresident)k
+// 238840inputs+295912outputs (428major+8489300minor)pagefaults 0swaps
+
+#ifndef FORTRAN_COMMON_VISIT_H_
+#define FORTRAN_COMMON_VISIT_H_
+
+#include <type_traits>
+#include <variant>
+
+namespace Fortran::common {
+namespace log2visit {
+
+template <std::size_t LOW, std::size_t HIGH, typename RESULT, typename VISITOR,
+ typename... VARIANT>
+inline RESULT Log2VisitHelper(
+ VISITOR &&visitor, std::size_t which, VARIANT &&...u) {
+ if constexpr (LOW == HIGH) {
+ return visitor(std::get<LOW>(std::forward<VARIANT>(u))...);
+ } else {
+ static constexpr std::size_t mid{(HIGH + LOW) / 2};
+ if (which <= mid) {
+ return Log2VisitHelper<LOW, mid, RESULT>(
+ std::forward<VISITOR>(visitor), which, std::forward<VARIANT>(u)...);
+ } else {
+ return Log2VisitHelper<(mid + 1), HIGH, RESULT>(
+ std::forward<VISITOR>(visitor), which, std::forward<VARIANT>(u)...);
+ }
+ }
+}
+
+template <typename VISITOR, typename... VARIANT>
+inline auto visit(VISITOR &&visitor, VARIANT &&...u)
+ -> decltype(visitor(std::get<0>(std::forward<VARIANT>(u))...)) {
+ using Result = decltype(visitor(std::get<0>(std::forward<VARIANT>(u))...));
+ if constexpr (sizeof...(u) == 1) {
+ static constexpr std::size_t high{
+ (std::variant_size_v<std::decay_t<decltype(u)>> * ...) - 1};
+ return Log2VisitHelper<0, high, Result>(std::forward<VISITOR>(visitor),
+ u.index()..., std::forward<VARIANT>(u)...);
+ } else {
+ // TODO: figure out how to do multiple variant arguments
+ return ::std::visit(
+ std::forward<VISITOR>(visitor), std::forward<VARIANT>(u)...);
+ }
+}
+
+} // namespace log2visit
+
+// Some versions of clang have bugs that cause compilation to hang
+// on these templates. MSVC and older GCC versions may work but are
+// not well tested. So enable only for GCC 9 and better.
+#if __GNUC__ < 9
+#define FLANG_USE_STD_VISIT
+#endif
+
+#ifdef FLANG_USE_STD_VISIT
+using ::std::visit;
+#else
+using Fortran::common::log2visit::visit;
+#endif
+
+} // namespace Fortran::common
+#endif // FORTRAN_COMMON_VISIT_H_
diff --git a/flang/include/flang/Evaluate/expression.h b/flang/include/flang/Evaluate/expression.h
index f24750e4f0944..90309affbe257 100644
--- a/flang/include/flang/Evaluate/expression.h
+++ b/flang/include/flang/Evaluate/expression.h
@@ -646,7 +646,7 @@ template <> class Relational<SomeType> {
EVALUATE_UNION_CLASS_BOILERPLATE(Relational)
static constexpr DynamicType GetType() { return Result::GetType(); }
int Rank() const {
- return std::visit([](const auto &x) { return x.Rank(); }, u);
+ return common::visit([](const auto &x) { return x.Rank(); }, u);
}
llvm::raw_ostream &AsFortran(llvm::raw_ostream &o) const;
common::MapTemplate<Relational, DirectlyComparableTypes> u;
diff --git a/flang/include/flang/Evaluate/fold-designator.h b/flang/include/flang/Evaluate/fold-designator.h
index 457e86d4fdad9..f246bd12020e0 100644
--- a/flang/include/flang/Evaluate/fold-designator.h
+++ b/flang/include/flang/Evaluate/fold-designator.h
@@ -67,7 +67,7 @@ class DesignatorFolder {
template <typename T>
std::optional<OffsetSymbol> FoldDesignator(const Expr<T> &expr) {
- return std::visit(
+ return common::visit(
[&](const auto &x) { return FoldDesignator(x, elementNumber_++); },
expr.u);
}
@@ -98,7 +98,7 @@ class DesignatorFolder {
template <typename T>
std::optional<OffsetSymbol> FoldDesignator(
const Expr<T> &expr, ConstantSubscript which) {
- return std::visit(
+ return common::visit(
[&](const auto &x) { return FoldDesignator(x, which); }, expr.u);
}
@@ -110,14 +110,14 @@ class DesignatorFolder {
template <typename T>
std::optional<OffsetSymbol> FoldDesignator(
const Designator<T> &designator, ConstantSubscript which) {
- return std::visit(
+ return common::visit(
[&](const auto &x) { return FoldDesignator(x, which); }, designator.u);
}
template <int KIND>
std::optional<OffsetSymbol> FoldDesignator(
const Designator<Type<TypeCategory::Character, KIND>> &designator,
ConstantSubscript which) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const Substring &ss) {
if (const auto *dataRef{ss.GetParentIf<DataRef>()}) {
diff --git a/flang/include/flang/Evaluate/initial-image.h b/flang/include/flang/Evaluate/initial-image.h
index 596b1f77d1790..fcc18835418a8 100644
--- a/flang/include/flang/Evaluate/initial-image.h
+++ b/flang/include/flang/Evaluate/initial-image.h
@@ -88,7 +88,7 @@ class InitialImage {
template <typename T>
Result Add(ConstantSubscript offset, std::size_t bytes, const Expr<T> &x,
FoldingContext &c) {
- return std::visit(
+ return common::visit(
[&](const auto &y) { return Add(offset, bytes, y, c); }, x.u);
}
diff --git a/flang/include/flang/Evaluate/shape.h b/flang/include/flang/Evaluate/shape.h
index 5cee3a3358165..60e71f2363e8c 100644
--- a/flang/include/flang/Evaluate/shape.h
+++ b/flang/include/flang/Evaluate/shape.h
@@ -167,7 +167,7 @@ class GetShapeHelper
template <typename T>
MaybeExtentExpr GetArrayConstructorValueExtent(
const ArrayConstructorValue<T> &value) const {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const Expr<T> &x) -> MaybeExtentExpr {
if (auto xShape{
diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h
index bba446749d12f..77810da17846d 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -83,7 +83,7 @@ template <typename A> bool IsAssumedRank(const Designator<A> &designator) {
}
}
template <typename T> bool IsAssumedRank(const Expr<T> &expr) {
- return std::visit([](const auto &x) { return IsAssumedRank(x); }, expr.u);
+ return common::visit([](const auto &x) { return IsAssumedRank(x); }, expr.u);
}
template <typename A> bool IsAssumedRank(const std::optional<A> &x) {
return x && IsAssumedRank(*x);
@@ -100,7 +100,7 @@ template <typename A> bool IsCoarray(const Designator<A> &designator) {
return false;
}
template <typename T> bool IsCoarray(const Expr<T> &expr) {
- return std::visit([](const auto &x) { return IsCoarray(x); }, expr.u);
+ return common::visit([](const auto &x) { return IsCoarray(x); }, expr.u);
}
template <typename A> bool IsCoarray(const std::optional<A> &x) {
return x && IsCoarray(*x);
@@ -177,11 +177,11 @@ auto UnwrapExpr(B &x) -> common::Constify<A, B> * {
return UnwrapExpr<A>(*expr);
}
} else if constexpr (std::is_same_v<Ty, Expr<SomeType>>) {
- return std::visit([](auto &x) { return UnwrapExpr<A>(x); }, x.u);
+ return common::visit([](auto &x) { return UnwrapExpr<A>(x); }, x.u);
} else if constexpr (!common::HasMember<A, TypelessExpression>) {
if constexpr (std::is_same_v<Ty, Expr<ResultType<A>>> ||
std::is_same_v<Ty, Expr<SomeKind<ResultType<A>::category>>>) {
- return std::visit([](auto &x) { return UnwrapExpr<A>(x); }, x.u);
+ return common::visit([](auto &x) { return UnwrapExpr<A>(x); }, x.u);
}
}
return nullptr;
@@ -217,15 +217,17 @@ auto UnwrapConvertedExpr(B &x) -> common::Constify<A, B> * {
return UnwrapConvertedExpr<A>(*expr);
}
} else if constexpr (std::is_same_v<Ty, Expr<SomeType>>) {
- return std::visit([](auto &x) { return UnwrapConvertedExpr<A>(x); }, x.u);
+ return common::visit(
+ [](auto &x) { return UnwrapConvertedExpr<A>(x); }, x.u);
} else if constexpr (!common::HasMember<A, TypelessExpression>) {
using Result = ResultType<A>;
if constexpr (std::is_same_v<Ty, Expr<Result>> ||
std::is_same_v<Ty, Expr<SomeKind<Result::category>>>) {
- return std::visit([](auto &x) { return UnwrapConvertedExpr<A>(x); }, x.u);
+ return common::visit(
+ [](auto &x) { return UnwrapConvertedExpr<A>(x); }, x.u);
} else if constexpr (std::is_same_v<Ty, Parentheses<Result>> ||
std::is_same_v<Ty, Convert<Result, Result::category>>) {
- return std::visit(
+ return common::visit(
[](auto &x) { return UnwrapConvertedExpr<A>(x); }, x.left().u);
}
}
@@ -262,7 +264,7 @@ common::IfNoLvalue<std::optional<DataRef>, A> ExtractDataRef(
template <typename T>
std::optional<DataRef> ExtractDataRef(
const Designator<T> &d, bool intoSubstring = false) {
- return std::visit(
+ return common::visit(
[=](const auto &x) -> std::optional<DataRef> {
if constexpr (common::HasMember<decltype(x), decltype(DataRef::u)>) {
return DataRef{x};
@@ -279,7 +281,7 @@ std::optional<DataRef> ExtractDataRef(
template <typename T>
std::optional<DataRef> ExtractDataRef(
const Expr<T> &expr, bool intoSubstring = false) {
- return std::visit(
+ return common::visit(
[=](const auto &x) { return ExtractDataRef(x, intoSubstring); }, expr.u);
}
template <typename A>
@@ -328,7 +330,7 @@ bool IsArrayElement(const Expr<T> &expr, bool intoSubstring = true,
template <typename A>
std::optional<NamedEntity> ExtractNamedEntity(const A &x) {
if (auto dataRef{ExtractDataRef(x, true)}) {
- return std::visit(
+ return common::visit(
common::visitors{
[](SymbolRef &&symbol) -> std::optional<NamedEntity> {
return NamedEntity{symbol};
@@ -354,10 +356,10 @@ struct ExtractCoindexedObjectHelper {
std::optional<CoarrayRef> operator()(const CoarrayRef &x) const { return x; }
template <typename A>
std::optional<CoarrayRef> operator()(const Expr<A> &expr) const {
- return std::visit(*this, expr.u);
+ return common::visit(*this, expr.u);
}
std::optional<CoarrayRef> operator()(const DataRef &dataRef) const {
- return std::visit(*this, dataRef.u);
+ return common::visit(*this, dataRef.u);
}
std::optional<CoarrayRef> operator()(const NamedEntity &named) const {
if (const Component * component{named.UnwrapComponent()}) {
@@ -470,7 +472,7 @@ Expr<TO> ConvertToType(Expr<SomeKind<FROMCAT>> &&x) {
ConvertToType<Part>(std::move(x)), Expr<Part>{Constant<Part>{zero}}}};
} else if constexpr (FROMCAT == TypeCategory::Complex) {
// Extract and convert the real component of a complex value
- return std::visit(
+ return common::visit(
[&](auto &&z) {
using ZType = ResultType<decltype(z)>;
using Part = typename ZType::Part;
@@ -524,7 +526,7 @@ common::IfNoLvalue<Expr<Type<TC, TK>>, FROM> ConvertTo(
template <TypeCategory TC, typename FROM>
common::IfNoLvalue<Expr<SomeKind<TC>>, FROM> ConvertTo(
const Expr<SomeKind<TC>> &to, FROM &&from) {
- return std::visit(
+ return common::visit(
[&](const auto &toKindExpr) {
using KindExpr = std::decay_t<decltype(toKindExpr)>;
return AsCategoryExpr(
@@ -536,7 +538,7 @@ common::IfNoLvalue<Expr<SomeKind<TC>>, FROM> ConvertTo(
template <typename FROM>
common::IfNoLvalue<Expr<SomeType>, FROM> ConvertTo(
const Expr<SomeType> &to, FROM &&from) {
- return std::visit(
+ return common::visit(
[&](const auto &toCatExpr) {
return AsGenericExpr(ConvertTo(toCatExpr, std::move(from)));
},
@@ -586,7 +588,7 @@ using SameKindExprs =
template <TypeCategory CAT>
SameKindExprs<CAT, 2> AsSameKindExprs(
Expr<SomeKind<CAT>> &&x, Expr<SomeKind<CAT>> &&y) {
- return std::visit(
+ return common::visit(
[&](auto &&kx, auto &&ky) -> SameKindExprs<CAT, 2> {
using XTy = ResultType<decltype(kx)>;
using YTy = ResultType<decltype(ky)>;
@@ -647,7 +649,7 @@ Expr<SPECIFIC> Combine(Expr<SPECIFIC> &&x, Expr<SPECIFIC> &&y) {
template <template <typename> class OPR, TypeCategory CAT>
Expr<SomeKind<CAT>> PromoteAndCombine(
Expr<SomeKind<CAT>> &&x, Expr<SomeKind<CAT>> &&y) {
- return std::visit(
+ return common::visit(
[](auto &&xy) {
using Ty = ResultType<decltype(xy[0])>;
return AsCategoryExpr(
@@ -748,7 +750,7 @@ Expr<Type<C, K>> operator/(Expr<Type<C, K>> &&x, Expr<Type<C, K>> &&y) {
}
template <TypeCategory C> Expr<SomeKind<C>> operator-(Expr<SomeKind<C>> &&x) {
- return std::visit(
+ return common::visit(
[](auto &xk) { return Expr<SomeKind<C>>{-std::move(xk)}; }, x.u);
}
@@ -893,7 +895,7 @@ std::optional<BaseObject> GetBaseObject(const Designator<T> &x) {
}
template <typename T>
std::optional<BaseObject> GetBaseObject(const Expr<T> &x) {
- return std::visit([](const auto &y) { return GetBaseObject(y); }, x.u);
+ return common::visit([](const auto &y) { return GetBaseObject(y); }, x.u);
}
template <typename A>
std::optional<BaseObject> GetBaseObject(const std::optional<A> &x) {
@@ -1035,7 +1037,8 @@ class ScalarConstantExpander {
return Expand(std::move(x.left())); // Constant<> can be parenthesized
}
template <typename T> Expr<T> Expand(Expr<T> &&x) {
- return std::visit([&](auto &&x) { return Expr<T>{Expand(std::move(x))}; },
+ return common::visit(
+ [&](auto &&x) { return Expr<T>{Expand(std::move(x))}; },
std::move(x.u));
}
diff --git a/flang/include/flang/Evaluate/traverse.h b/flang/include/flang/Evaluate/traverse.h
index 7a5a4ec9ff873..d7efa17f60bd0 100644
--- a/flang/include/flang/Evaluate/traverse.h
+++ b/flang/include/flang/Evaluate/traverse.h
@@ -78,7 +78,7 @@ template <typename Visitor, typename Result> class Traverse {
}
template <typename... A>
Result operator()(const std::variant<A...> &u) const {
- return std::visit(visitor_, u);
+ return common::visit(visitor_, u);
}
template <typename A> Result operator()(const std::vector<A> &x) const {
return CombineContents(x);
diff --git a/flang/include/flang/Parser/parse-tree-visitor.h b/flang/include/flang/Parser/parse-tree-visitor.h
index 179d9c263378b..4e749d3c8b4e1 100644
--- a/flang/include/flang/Parser/parse-tree-visitor.h
+++ b/flang/include/flang/Parser/parse-tree-visitor.h
@@ -10,6 +10,7 @@
#define FORTRAN_PARSER_PARSE_TREE_VISITOR_H_
#include "parse-tree.h"
+#include "flang/Common/visit.h"
#include <cstddef>
#include <optional>
#include <tuple>
@@ -133,14 +134,14 @@ void Walk(std::tuple<A...> &x, M &mutator) {
template <typename V, typename... A>
void Walk(const std::variant<A...> &x, V &visitor) {
if (visitor.Pre(x)) {
- std::visit([&](const auto &y) { Walk(y, visitor); }, x);
+ common::visit([&](const auto &y) { Walk(y, visitor); }, x);
visitor.Post(x);
}
}
template <typename M, typename... A>
void Walk(std::variant<A...> &x, M &mutator) {
if (mutator.Pre(x)) {
- std::visit([&](auto &y) { Walk(y, mutator); }, x);
+ common::visit([&](auto &y) { Walk(y, mutator); }, x);
mutator.Post(x);
}
}
diff --git a/flang/include/flang/Parser/tools.h b/flang/include/flang/Parser/tools.h
index 0261d8f0cf48e..48c6ab56dd9fd 100644
--- a/flang/include/flang/Parser/tools.h
+++ b/flang/include/flang/Parser/tools.h
@@ -62,7 +62,7 @@ struct UnwrapperHelper {
template <typename A, typename... Bs>
static const A *Unwrap(const std::variant<Bs...> &x) {
- return std::visit([](const auto &y) { return Unwrap<A>(y); }, x);
+ return common::visit([](const auto &y) { return Unwrap<A>(y); }, x);
}
template <typename A, typename B>
diff --git a/flang/include/flang/Semantics/expression.h b/flang/include/flang/Semantics/expression.h
index 7c9e4ff4473e5..1cf5506748b1c 100644
--- a/flang/include/flang/Semantics/expression.h
+++ b/flang/include/flang/Semantics/expression.h
@@ -13,6 +13,7 @@
#include "flang/Common/Fortran.h"
#include "flang/Common/indirection.h"
#include "flang/Common/restorer.h"
+#include "flang/Common/visit.h"
#include "flang/Evaluate/characteristics.h"
#include "flang/Evaluate/check-expression.h"
#include "flang/Evaluate/expression.h"
@@ -299,11 +300,7 @@ class ExpressionAnalyzer {
return Analyze(x.u); // default case
}
template <typename... As> MaybeExpr Analyze(const std::variant<As...> &u) {
- return std::visit(
- [&](const auto &x) {
- return Analyze(x);
- },
- u);
+ return common::visit([&](const auto &x) { return Analyze(x); }, u);
}
// Analysis subroutines
diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 7074d53db4d03..f836da4b3da0e 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -13,6 +13,7 @@
#include "flang/Common/Fortran.h"
#include "flang/Common/enum-set.h"
#include "flang/Common/reference.h"
+#include "flang/Common/visit.h"
#include "llvm/ADT/DenseMapInfo.h"
#include <array>
#include <functional>
@@ -612,24 +613,24 @@ class Symbol {
bool IsSubprogram() const;
bool IsFromModFile() const;
bool HasExplicitInterface() const {
- return std::visit(common::visitors{
- [](const SubprogramDetails &) { return true; },
- [](const SubprogramNameDetails &) { return true; },
- [&](const ProcEntityDetails &x) {
- return attrs_.test(Attr::INTRINSIC) ||
- x.HasExplicitInterface();
- },
- [](const ProcBindingDetails &x) {
- return x.symbol().HasExplicitInterface();
- },
- [](const UseDetails &x) {
- return x.symbol().HasExplicitInterface();
- },
- [](const HostAssocDetails &x) {
- return x.symbol().HasExplicitInterface();
- },
- [](const auto &) { return false; },
- },
+ return common::visit(common::visitors{
+ [](const SubprogramDetails &) { return true; },
+ [](const SubprogramNameDetails &) { return true; },
+ [&](const ProcEntityDetails &x) {
+ return attrs_.test(Attr::INTRINSIC) ||
+ x.HasExplicitInterface();
+ },
+ [](const ProcBindingDetails &x) {
+ return x.symbol().HasExplicitInterface();
+ },
+ [](const UseDetails &x) {
+ return x.symbol().HasExplicitInterface();
+ },
+ [](const HostAssocDetails &x) {
+ return x.symbol().HasExplicitInterface();
+ },
+ [](const auto &) { return false; },
+ },
details_);
}
@@ -637,7 +638,7 @@ class Symbol {
bool operator!=(const Symbol &that) const { return !(*this == that); }
int Rank() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](const SubprogramDetails &sd) {
return sd.isFunction() ? sd.result().Rank() : 0;
@@ -670,7 +671,7 @@ class Symbol {
}
int Corank() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](const SubprogramDetails &sd) {
return sd.isFunction() ? sd.result().Corank() : 0;
@@ -786,7 +787,7 @@ inline DeclTypeSpec *Symbol::GetType() {
const_cast<const Symbol *>(this)->GetType());
}
inline const DeclTypeSpec *Symbol::GetType() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](const EntityDetails &x) { return x.type(); },
[](const ObjectEntityDetails &x) { return x.type(); },
diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h
index 1ee21041dcc27..4f06af023dfb9 100644
--- a/flang/include/flang/Semantics/tools.h
+++ b/flang/include/flang/Semantics/tools.h
@@ -13,6 +13,7 @@
// canonically for use in semantic checking.
#include "flang/Common/Fortran.h"
+#include "flang/Common/visit.h"
#include "flang/Evaluate/expression.h"
#include "flang/Evaluate/shape.h"
#include "flang/Evaluate/type.h"
@@ -239,7 +240,7 @@ const Symbol *FindExternallyVisibleObject(
template <typename T>
const Symbol *FindExternallyVisibleObject(
const evaluate::Expr<T> &expr, const Scope &scope) {
- return std::visit(
+ return common::visit(
[&](const auto &x) { return FindExternallyVisibleObject(x, scope); },
expr.u);
}
diff --git a/flang/lib/Evaluate/call.cpp b/flang/lib/Evaluate/call.cpp
index 9328ff79852ec..75bc3939c00ee 100644
--- a/flang/lib/Evaluate/call.cpp
+++ b/flang/lib/Evaluate/call.cpp
@@ -157,18 +157,19 @@ const Component *ProcedureDesignator::GetComponent() const {
}
const Symbol *ProcedureDesignator::GetSymbol() const {
- return std::visit(common::visitors{
- [](SymbolRef symbol) { return &*symbol; },
- [](const common::CopyableIndirection<Component> &c) {
- return &c.value().GetLastSymbol();
- },
- [](const auto &) -> const Symbol * { return nullptr; },
- },
+ return common::visit(
+ common::visitors{
+ [](SymbolRef symbol) { return &*symbol; },
+ [](const common::CopyableIndirection<Component> &c) {
+ return &c.value().GetLastSymbol();
+ },
+ [](const auto &) -> const Symbol * { return nullptr; },
+ },
u);
}
std::string ProcedureDesignator::GetName() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](const SpecificIntrinsic &i) { return i.name; },
[](const Symbol &symbol) { return symbol.name().ToString(); },
diff --git a/flang/lib/Evaluate/characteristics.cpp b/flang/lib/Evaluate/characteristics.cpp
index e79c563c136f2..474c6080a0861 100644
--- a/flang/lib/Evaluate/characteristics.cpp
+++ b/flang/lib/Evaluate/characteristics.cpp
@@ -69,7 +69,7 @@ TypeAndShape &TypeAndShape::Rewrite(FoldingContext &context) {
std::optional<TypeAndShape> TypeAndShape::Characterize(
const semantics::Symbol &symbol, FoldingContext &context) {
const auto &ultimate{symbol.GetUltimate()};
- return std::visit(
+ return common::visit(
common::visitors{
[&](const semantics::ProcEntityDetails &proc) {
const semantics::ProcInterface &interface{proc.interface()};
@@ -392,7 +392,7 @@ static std::optional<Procedure> CharacterizeProcedure(
result.attrs.test(Procedure::Attr::Elemental))) {
result.attrs.set(Procedure::Attr::Pure);
}
- return std::visit(
+ return common::visit(
common::visitors{
[&](const semantics::SubprogramDetails &subp)
-> std::optional<Procedure> {
@@ -578,7 +578,7 @@ static std::optional<DummyArgument> CharacterizeDummyArgument(
std::optional<DummyArgument> DummyArgument::FromActual(
std::string &&name, const Expr<SomeType> &expr, FoldingContext &context) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const BOZLiteralConstant &) {
return std::make_optional<DummyArgument>(std::move(name),
@@ -619,7 +619,7 @@ std::optional<DummyArgument> DummyArgument::FromActual(
}
bool DummyArgument::IsOptional() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](const DummyDataObject &data) {
return data.attrs.test(DummyDataObject::Attr::Optional);
@@ -633,35 +633,36 @@ bool DummyArgument::IsOptional() const {
}
void DummyArgument::SetOptional(bool value) {
- std::visit(common::visitors{
- [value](DummyDataObject &data) {
- data.attrs.set(DummyDataObject::Attr::Optional, value);
- },
- [value](DummyProcedure &proc) {
- proc.attrs.set(DummyProcedure::Attr::Optional, value);
- },
- [](AlternateReturn &) { DIE("cannot set optional"); },
- },
+ common::visit(common::visitors{
+ [value](DummyDataObject &data) {
+ data.attrs.set(DummyDataObject::Attr::Optional, value);
+ },
+ [value](DummyProcedure &proc) {
+ proc.attrs.set(DummyProcedure::Attr::Optional, value);
+ },
+ [](AlternateReturn &) { DIE("cannot set optional"); },
+ },
u);
}
void DummyArgument::SetIntent(common::Intent intent) {
- std::visit(common::visitors{
- [intent](DummyDataObject &data) { data.intent = intent; },
- [intent](DummyProcedure &proc) { proc.intent = intent; },
- [](AlternateReturn &) { DIE("cannot set intent"); },
- },
+ common::visit(common::visitors{
+ [intent](DummyDataObject &data) { data.intent = intent; },
+ [intent](DummyProcedure &proc) { proc.intent = intent; },
+ [](AlternateReturn &) { DIE("cannot set intent"); },
+ },
u);
}
common::Intent DummyArgument::GetIntent() const {
- return std::visit(common::visitors{
- [](const DummyDataObject &data) { return data.intent; },
- [](const DummyProcedure &proc) { return proc.intent; },
- [](const AlternateReturn &) -> common::Intent {
- DIE("Alternate returns have no intent");
- },
- },
+ return common::visit(
+ common::visitors{
+ [](const DummyDataObject &data) { return data.intent; },
+ [](const DummyProcedure &proc) { return proc.intent; },
+ [](const AlternateReturn &) -> common::Intent {
+ DIE("Alternate returns have no intent");
+ },
+ },
u);
}
@@ -685,7 +686,7 @@ llvm::raw_ostream &DummyArgument::Dump(llvm::raw_ostream &o) const {
if (pass) {
o << " PASS";
}
- std::visit([&](const auto &x) { x.Dump(o); }, u);
+ common::visit([&](const auto &x) { x.Dump(o); }, u);
return o;
}
@@ -798,12 +799,12 @@ bool FunctionResult::IsCompatibleWith(const FunctionResult &actual) const {
llvm::raw_ostream &FunctionResult::Dump(llvm::raw_ostream &o) const {
attrs.Dump(o, EnumToString);
- std::visit(common::visitors{
- [&](const TypeAndShape &ts) { ts.Dump(o); },
- [&](const CopyableIndirection<Procedure> &p) {
- p.value().Dump(o << " procedure(") << ')';
- },
- },
+ common::visit(common::visitors{
+ [&](const TypeAndShape &ts) { ts.Dump(o); },
+ [&](const CopyableIndirection<Procedure> &p) {
+ p.value().Dump(o << " procedure(") << ')';
+ },
+ },
u);
return o;
}
@@ -1135,7 +1136,7 @@ bool DistinguishUtils::Distinguishable(
if (x.u.index() != y.u.index()) {
return true; //
diff erent kind: data/proc/alt-return
}
- return std::visit(
+ return common::visit(
common::visitors{
[&](const DummyDataObject &z) {
return Distinguishable(z, std::get<DummyDataObject>(y.u));
@@ -1197,7 +1198,7 @@ bool DistinguishUtils::Distinguishable(
if (x.u.index() != y.u.index()) {
return true; // one is data object, one is procedure
}
- return std::visit(
+ return common::visit(
common::visitors{
[&](const TypeAndShape &z) {
return Distinguishable(z, std::get<TypeAndShape>(y.u));
diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp
index c184fdc78a76b..588fe3b609297 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -173,13 +173,13 @@ struct IsActuallyConstantHelper {
return (*this)(x.left());
}
template <typename T> bool operator()(const Expr<T> &x) {
- return std::visit([=](const auto &y) { return (*this)(y); }, x.u);
+ return common::visit([=](const auto &y) { return (*this)(y); }, x.u);
}
bool operator()(const Expr<SomeType> &x) {
if (IsNullPointer(x)) {
return true;
}
- return std::visit([this](const auto &y) { return (*this)(y); }, x.u);
+ return common::visit([this](const auto &y) { return (*this)(y); }, x.u);
}
template <typename A> bool operator()(const A *x) { return x && (*this)(*x); }
template <typename A> bool operator()(const std::optional<A> &x) {
@@ -256,13 +256,13 @@ class IsInitialDataTargetHelper
IsConstantExpr(x.stride());
}
bool operator()(const Subscript &x) const {
- return std::visit(common::visitors{
- [&](const Triplet &t) { return (*this)(t); },
- [&](const auto &y) {
- return y.value().Rank() == 0 &&
- IsConstantExpr(y.value());
- },
- },
+ return common::visit(common::visitors{
+ [&](const Triplet &t) { return (*this)(t); },
+ [&](const auto &y) {
+ return y.value().Rank() == 0 &&
+ IsConstantExpr(y.value());
+ },
+ },
x.u);
}
bool operator()(const CoarrayRef &) const { return false; }
@@ -334,7 +334,7 @@ bool IsInitialDataTarget(
bool IsInitialProcedureTarget(const semantics::Symbol &symbol) {
const auto &ultimate{symbol.GetUltimate()};
- return std::visit(
+ return common::visit(
common::visitors{
[](const semantics::SubprogramDetails &subp) {
return !subp.isDummy();
@@ -383,7 +383,7 @@ class ArrayConstantBoundChanger {
std::move(x.left())); // Constant<> can be parenthesized
}
template <typename T> Expr<T> ChangeLbounds(Expr<T> &&x) {
- return std::visit(
+ return common::visit(
[&](auto &&x) { return Expr<T>{ChangeLbounds(std::move(x))}; },
std::move(x.u)); // recurse until we hit a constant
}
diff --git a/flang/lib/Evaluate/expression.cpp b/flang/lib/Evaluate/expression.cpp
index 1f255e61f37a9..3ea99c8962eac 100644
--- a/flang/lib/Evaluate/expression.cpp
+++ b/flang/lib/Evaluate/expression.cpp
@@ -30,7 +30,7 @@ template <int KIND>
std::optional<Expr<SubscriptInteger>>
Expr<Type<TypeCategory::Character, KIND>>::LEN() const {
using T = std::optional<Expr<SubscriptInteger>>;
- return std::visit(
+ return common::visit(
common::visitors{
[](const Constant<Result> &c) -> T {
return AsExpr(Constant<SubscriptInteger>{c.LEN()});
@@ -38,7 +38,7 @@ Expr<Type<TypeCategory::Character, KIND>>::LEN() const {
[](const ArrayConstructor<Result> &a) -> T { return a.LEN(); },
[](const Parentheses<Result> &x) { return x.left().LEN(); },
[](const Convert<Result> &x) {
- return std::visit(
+ return common::visit(
[&](const auto &kx) { return kx.LEN(); }, x.left().u);
},
[](const Concat<KIND> &c) -> T {
@@ -84,7 +84,7 @@ std::optional<DynamicType> ExpressionBase<A>::GetType() const {
if constexpr (IsLengthlessIntrinsicType<Result>) {
return Result::GetType();
} else {
- return std::visit(
+ return common::visit(
[&](const auto &x) -> std::optional<DynamicType> {
if constexpr (!common::HasMember<decltype(x), TypelessExpression>) {
return x.GetType();
@@ -96,7 +96,7 @@ std::optional<DynamicType> ExpressionBase<A>::GetType() const {
}
template <typename A> int ExpressionBase<A>::Rank() const {
- return std::visit(
+ return common::visit(
[](const auto &x) {
if constexpr (common::HasMember<decltype(x), TypelessExpression>) {
return 0;
@@ -309,19 +309,19 @@ void GenericAssignmentWrapper::Deleter(GenericAssignmentWrapper *p) {
}
template <TypeCategory CAT> int Expr<SomeKind<CAT>>::GetKind() const {
- return std::visit(
+ return common::visit(
[](const auto &kx) { return std::decay_t<decltype(kx)>::Result::kind; },
u);
}
int Expr<SomeCharacter>::GetKind() const {
- return std::visit(
+ return common::visit(
[](const auto &kx) { return std::decay_t<decltype(kx)>::Result::kind; },
u);
}
std::optional<Expr<SubscriptInteger>> Expr<SomeCharacter>::LEN() const {
- return std::visit([](const auto &kx) { return kx.LEN(); }, u);
+ return common::visit([](const auto &kx) { return kx.LEN(); }, u);
}
#ifdef _MSC_VER // disable bogus warning about missing definitions
diff --git a/flang/lib/Evaluate/fold-designator.cpp b/flang/lib/Evaluate/fold-designator.cpp
index e00bb09a3c74a..2168383bc7318 100644
--- a/flang/lib/Evaluate/fold-designator.cpp
+++ b/flang/lib/Evaluate/fold-designator.cpp
@@ -70,7 +70,7 @@ std::optional<OffsetSymbol> DesignatorFolder::FoldDesignator(
ConstantSubscript lower{lowerBounds->at(dim)};
ConstantSubscript extent{extents->at(dim)};
ConstantSubscript upper{lower + extent - 1};
- if (!std::visit(
+ if (!common::visit(
common::visitors{
[&](const IndirectSubscriptIntegerExpr &expr) {
auto folded{
@@ -169,7 +169,7 @@ std::optional<OffsetSymbol> DesignatorFolder::FoldDesignator(
std::optional<OffsetSymbol> DesignatorFolder::FoldDesignator(
const DataRef &dataRef, ConstantSubscript which) {
- return std::visit(
+ return common::visit(
[&](const auto &x) { return FoldDesignator(x, which); }, dataRef.u);
}
@@ -317,7 +317,7 @@ std::optional<Expr<SomeType>> OffsetToDesignator(FoldingContext &context,
// Pick a COMPLEX component
auto part{
offset == 0 ? ComplexPart::Part::RE : ComplexPart::Part::IM};
- return std::visit(
+ return common::visit(
[&](const auto &z) -> std::optional<Expr<SomeType>> {
using PartType = typename ResultType<decltype(z)>::Part;
return AsGenericExpr(Designator<PartType>{ComplexPart{
@@ -329,7 +329,7 @@ std::optional<Expr<SomeType>> OffsetToDesignator(FoldingContext &context,
std::get_if<Expr<SomeCharacter>>(&result->u)}) {
if (offset > 0 || size != static_cast<std::size_t>(*elementBytes)) {
// Select a substring
- return std::visit(
+ return common::visit(
[&](const auto &x) -> std::optional<Expr<SomeType>> {
using T = typename std::decay_t<decltype(x)>::Result;
return AsGenericExpr(Designator<T>{
diff --git a/flang/lib/Evaluate/fold-implementation.h b/flang/lib/Evaluate/fold-implementation.h
index 34a4ce8cf5701..2e12b502d0fc0 100644
--- a/flang/lib/Evaluate/fold-implementation.h
+++ b/flang/lib/Evaluate/fold-implementation.h
@@ -303,7 +303,7 @@ std::optional<Constant<T>> Folder<T>::ApplyComponent(
template <typename T>
std::optional<Constant<T>> Folder<T>::GetConstantComponent(Component &component,
const std::vector<Constant<SubscriptInteger>> *subscripts) {
- if (std::optional<Constant<SomeDerived>> structures{std::visit(
+ if (std::optional<Constant<SomeDerived>> structures{common::visit(
common::visitors{
[&](const Symbol &symbol) {
return Folder<SomeDerived>{context_}.GetNamedConstant(symbol);
@@ -342,7 +342,7 @@ template <typename T> Expr<T> Folder<T>::Folding(Designator<T> &&designator) {
}
}
}
- return std::visit(
+ return common::visit(
common::visitors{
[&](SymbolRef &&symbol) {
if (auto constant{GetNamedConstant(*symbol)}) {
@@ -523,7 +523,7 @@ template <typename A, typename B>
std::optional<std::vector<A>> GetIntegerVector(const B &x) {
static_assert(std::is_integral_v<A>);
if (const auto *someInteger{UnwrapExpr<Expr<SomeInteger>>(x)}) {
- return std::visit(
+ return common::visit(
[](const auto &typedExpr) -> std::optional<std::vector<A>> {
using T = ResultType<decltype(typedExpr)>;
if (const auto *constant{UnwrapConstantValue<T>(typedExpr)}) {
@@ -1039,10 +1039,10 @@ Expr<T> RewriteSpecificMINorMAX(
return Fold(context, ConvertToType<T>(AsCategoryExpr(std::move(maxRef))));
}};
if (auto *sx{UnwrapExpr<Expr<SomeReal>>(*resultTypeArg)}) {
- return std::visit(insertConversion, sx->u);
+ return common::visit(insertConversion, sx->u);
}
auto &sx{DEREF(UnwrapExpr<Expr<SomeInteger>>(*resultTypeArg))};
- return std::visit(insertConversion, sx.u);
+ return common::visit(insertConversion, sx.u);
}
template <typename T>
@@ -1164,7 +1164,7 @@ template <typename T> class ArrayConstructorFolder {
}
}
bool FoldArray(const ArrayConstructorValue<T> &x) {
- return std::visit([&](const auto &y) { return FoldArray(y); }, x.u);
+ return common::visit([&](const auto &y) { return FoldArray(y); }, x.u);
}
bool FoldArray(const ArrayConstructorValues<T> &xs) {
for (const auto &x : xs) {
@@ -1227,7 +1227,7 @@ template <TypeCategory CAT>
std::enable_if_t<CAT != TypeCategory::Derived,
std::optional<Expr<SomeKind<CAT>>>>
AsFlatArrayConstructor(const Expr<SomeKind<CAT>> &expr) {
- return std::visit(
+ return common::visit(
[&](const auto &kindExpr) -> std::optional<Expr<SomeKind<CAT>>> {
if (auto flattened{AsFlatArrayConstructor(kindExpr)}) {
return Expr<SomeKind<CAT>>{std::move(*flattened)};
@@ -1268,7 +1268,7 @@ Expr<RESULT> MapOperation(FoldingContext &context,
Expr<OPERAND> &&values) {
ArrayConstructor<RESULT> result{values};
if constexpr (common::HasMember<OPERAND, AllIntrinsicCategoryTypes>) {
- std::visit(
+ common::visit(
[&](auto &&kindExpr) {
using kindType = ResultType<decltype(kindExpr)>;
auto &aConst{std::get<ArrayConstructor<kindType>>(kindExpr.u)};
@@ -1309,7 +1309,7 @@ Expr<RESULT> MapOperation(FoldingContext &context,
auto result{ArrayConstructorFromMold<RESULT>(leftValues, std::move(length))};
auto &leftArrConst{std::get<ArrayConstructor<LEFT>>(leftValues.u)};
if constexpr (common::HasMember<RIGHT, AllIntrinsicCategoryTypes>) {
- std::visit(
+ common::visit(
[&](auto &&kindExpr) {
using kindType = ResultType<decltype(kindExpr)>;
@@ -1366,7 +1366,7 @@ Expr<RESULT> MapOperation(FoldingContext &context,
const Expr<LEFT> &leftScalar, Expr<RIGHT> &&rightValues) {
auto result{ArrayConstructorFromMold<RESULT>(leftScalar, std::move(length))};
if constexpr (common::HasMember<RIGHT, AllIntrinsicCategoryTypes>) {
- std::visit(
+ common::visit(
[&](auto &&kindExpr) {
using kindType = ResultType<decltype(kindExpr)>;
auto &rightArrConst{std::get<ArrayConstructor<kindType>>(kindExpr.u)};
@@ -1518,7 +1518,7 @@ Expr<TO> FoldOperation(
FoldingContext &context;
Convert<TO, FROMCAT> &convert;
} msvcWorkaround{context, convert};
- return std::visit(
+ return common::visit(
[&msvcWorkaround](auto &kindExpr) -> Expr<TO> {
using Operand = ResultType<decltype(kindExpr)>;
// This variable is a workaround for msvc which emits an error when
@@ -1839,7 +1839,7 @@ Expr<T> FoldOperation(FoldingContext &context, RealToIntPower<T> &&x) {
if (auto array{ApplyElementwise(context, x)}) {
return *array;
}
- return std::visit(
+ return common::visit(
[&](auto &y) -> Expr<T> {
if (auto folded{OperandsAreConstants(x.left(), y)}) {
auto power{evaluate::IntPower(folded->first, folded->second)};
@@ -1897,7 +1897,7 @@ Expr<Type<TypeCategory::Real, KIND>> ToReal(
FoldingContext &context, Expr<SomeType> &&expr) {
using Result = Type<TypeCategory::Real, KIND>;
std::optional<Expr<Result>> result;
- std::visit(
+ common::visit(
[&](auto &&x) {
using From = std::decay_t<decltype(x)>;
if constexpr (std::is_same_v<From, BOZLiteralConstant>) {
@@ -1924,7 +1924,7 @@ Expr<Type<TypeCategory::Real, KIND>> ToReal(
template <typename T>
Expr<T> ExpressionBase<T>::Rewrite(FoldingContext &context, Expr<T> &&expr) {
- return std::visit(
+ return common::visit(
[&](auto &&x) -> Expr<T> {
if constexpr (IsSpecificIntrinsicType<T>) {
return FoldOperation(context, std::move(x));
diff --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp
index d1a87dd5a8474..d07af216d230a 100644
--- a/flang/lib/Evaluate/fold-integer.cpp
+++ b/flang/lib/Evaluate/fold-integer.cpp
@@ -37,7 +37,7 @@ class GetConstantArrayLboundHelper {
template <typename T> ConstantSubscript GetLbound(const Expr<T> &x) {
// recurse through Expr<T>'a until we hit a constant
- return std::visit([&](const auto &inner) { return GetLbound(inner); },
+ return common::visit([&](const auto &inner) { return GetLbound(inner); },
// [&](const auto &) { return 0; },
x.u);
}
@@ -431,7 +431,7 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
common::RoundingMode mode{name == "ceiling" ? common::RoundingMode::Up
: name == "floor" ? common::RoundingMode::Down
: common::RoundingMode::TiesAwayFromZero};
- return std::visit(
+ return common::visit(
[&](const auto &kx) {
using TR = ResultType<decltype(kx)>;
return FoldElementalIntrinsic<T, TR>(context, std::move(funcRef),
@@ -450,19 +450,19 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
return FoldCount<T>(context, std::move(funcRef));
} else if (name == "digits") {
if (const auto *cx{UnwrapExpr<Expr<SomeInteger>>(args[0])}) {
- return Expr<T>{std::visit(
+ return Expr<T>{common::visit(
[](const auto &kx) {
return Scalar<ResultType<decltype(kx)>>::DIGITS;
},
cx->u)};
} else if (const auto *cx{UnwrapExpr<Expr<SomeReal>>(args[0])}) {
- return Expr<T>{std::visit(
+ return Expr<T>{common::visit(
[](const auto &kx) {
return Scalar<ResultType<decltype(kx)>>::DIGITS;
},
cx->u)};
} else if (const auto *cx{UnwrapExpr<Expr<SomeComplex>>(args[0])}) {
- return Expr<T>{std::visit(
+ return Expr<T>{common::visit(
[](const auto &kx) {
return Scalar<typename ResultType<decltype(kx)>::Part>::DIGITS;
},
@@ -484,7 +484,7 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
}));
} else if (name == "exponent") {
if (auto *sx{UnwrapExpr<Expr<SomeReal>>(args[0])}) {
- return std::visit(
+ return common::visit(
[&funcRef, &context](const auto &x) -> Expr<T> {
using TR = typename std::decay_t<decltype(x)>::Result;
return FoldElementalIntrinsic<T, TR>(context, std::move(funcRef),
@@ -508,7 +508,7 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
"Character in intrinsic function %s must have length one"_warn_en_US,
name);
} else {
- return std::visit(
+ return common::visit(
[&funcRef, &context](const auto &str) -> Expr<T> {
using Char = typename std::decay_t<decltype(str)>::Result;
return FoldElementalIntrinsic<T, Char>(context,
@@ -586,7 +586,7 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
}));
} else if (name == "index" || name == "scan" || name == "verify") {
if (auto *charExpr{UnwrapExpr<Expr<SomeCharacter>>(args[0])}) {
- return std::visit(
+ return common::visit(
[&](const auto &kch) -> Expr<T> {
using TC = typename std::decay_t<decltype(kch)>::Result;
if (UnwrapExpr<Expr<SomeLogical>>(args[2])) { // BACK=
@@ -623,7 +623,7 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
}
} else if (name == "int") {
if (auto *expr{UnwrapExpr<Expr<SomeType>>(args[0])}) {
- return std::visit(
+ return common::visit(
[&](auto &&x) -> Expr<T> {
using From = std::decay_t<decltype(x)>;
if constexpr (std::is_same_v<From, BOZLiteralConstant> ||
@@ -666,7 +666,7 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
} else if (name == "leadz" || name == "trailz" || name == "poppar" ||
name == "popcnt") {
if (auto *sn{UnwrapExpr<Expr<SomeInteger>>(args[0])}) {
- return std::visit(
+ return common::visit(
[&funcRef, &context, &name](const auto &n) -> Expr<T> {
using TI = typename std::decay_t<decltype(n)>::Result;
if (name == "poppar") {
@@ -696,7 +696,7 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
}
} else if (name == "len") {
if (auto *charExpr{UnwrapExpr<Expr<SomeCharacter>>(args[0])}) {
- return std::visit(
+ return common::visit(
[&](auto &kx) {
if (auto len{kx.LEN()}) {
if (IsScopeInvariantExpr(*len)) {
@@ -714,7 +714,7 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
}
} else if (name == "len_trim") {
if (auto *charExpr{UnwrapExpr<Expr<SomeCharacter>>(args[0])}) {
- return std::visit(
+ return common::visit(
[&](const auto &kch) -> Expr<T> {
using TC = typename std::decay_t<decltype(kch)>::Result;
return FoldElementalIntrinsic<T, TC>(context, std::move(funcRef),
@@ -740,7 +740,7 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
return RewriteSpecificMINorMAX(context, std::move(funcRef));
} else if (name == "maxexponent") {
if (auto *sx{UnwrapExpr<Expr<SomeReal>>(args[0])}) {
- return std::visit(
+ return common::visit(
[](const auto &x) {
using TR = typename std::decay_t<decltype(x)>::Result;
return Expr<T>{Scalar<TR>::MAXEXPONENT};
@@ -763,7 +763,7 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
return RewriteSpecificMINorMAX(context, std::move(funcRef));
} else if (name == "minexponent") {
if (auto *sx{UnwrapExpr<Expr<SomeReal>>(args[0])}) {
- return std::visit(
+ return common::visit(
[](const auto &x) {
using TR = typename std::decay_t<decltype(x)>::Result;
return Expr<T>{Scalar<TR>::MINEXPONENT};
@@ -805,13 +805,13 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
context, std::move(funcRef), &Scalar<T>::NOT);
} else if (name == "precision") {
if (const auto *cx{UnwrapExpr<Expr<SomeReal>>(args[0])}) {
- return Expr<T>{std::visit(
+ return Expr<T>{common::visit(
[](const auto &kx) {
return Scalar<ResultType<decltype(kx)>>::PRECISION;
},
cx->u)};
} else if (const auto *cx{UnwrapExpr<Expr<SomeComplex>>(args[0])}) {
- return Expr<T>{std::visit(
+ return Expr<T>{common::visit(
[](const auto &kx) {
return Scalar<typename ResultType<decltype(kx)>::Part>::PRECISION;
},
@@ -823,19 +823,19 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
return Expr<T>{2};
} else if (name == "range") {
if (const auto *cx{UnwrapExpr<Expr<SomeInteger>>(args[0])}) {
- return Expr<T>{std::visit(
+ return Expr<T>{common::visit(
[](const auto &kx) {
return Scalar<ResultType<decltype(kx)>>::RANGE;
},
cx->u)};
} else if (const auto *cx{UnwrapExpr<Expr<SomeReal>>(args[0])}) {
- return Expr<T>{std::visit(
+ return Expr<T>{common::visit(
[](const auto &kx) {
return Scalar<ResultType<decltype(kx)>>::RANGE;
},
cx->u)};
} else if (const auto *cx{UnwrapExpr<Expr<SomeComplex>>(args[0])}) {
- return Expr<T>{std::visit(
+ return Expr<T>{common::visit(
[](const auto &kx) {
return Scalar<typename ResultType<decltype(kx)>::Part>::RANGE;
},
@@ -1036,7 +1036,7 @@ Expr<TypeParamInquiry::Result> FoldOperation(
}
std::optional<std::int64_t> ToInt64(const Expr<SomeInteger> &expr) {
- return std::visit(
+ return common::visit(
[](const auto &kindExpr) { return ToInt64(kindExpr); }, expr.u);
}
diff --git a/flang/lib/Evaluate/fold-logical.cpp b/flang/lib/Evaluate/fold-logical.cpp
index 34a7639ba32d1..fe18ae211bd2a 100644
--- a/flang/lib/Evaluate/fold-logical.cpp
+++ b/flang/lib/Evaluate/fold-logical.cpp
@@ -91,7 +91,7 @@ Expr<Type<TypeCategory::Logical, KIND>> FoldIntrinsicFunction(
}));
} else if (name == "btest") {
if (const auto *ix{UnwrapExpr<Expr<SomeInteger>>(args[0])}) {
- return std::visit(
+ return common::visit(
[&](const auto &x) {
using IT = ResultType<decltype(x)>;
return FoldElementalIntrinsic<T, IT, SameInt>(context,
@@ -212,7 +212,7 @@ Expr<LogicalResult> FoldOperation(
Expr<LogicalResult> FoldOperation(
FoldingContext &context, Relational<SomeType> &&relation) {
- return std::visit(
+ return common::visit(
[&](auto &&x) {
return Expr<LogicalResult>{FoldOperation(context, std::move(x))};
},
diff --git a/flang/lib/Evaluate/fold-real.cpp b/flang/lib/Evaluate/fold-real.cpp
index 1fab0ba6d6e85..a1d12c427d41b 100644
--- a/flang/lib/Evaluate/fold-real.cpp
+++ b/flang/lib/Evaluate/fold-real.cpp
@@ -121,7 +121,7 @@ Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction(
return FoldMerge<T>(context, std::move(funcRef));
} else if (name == "nearest") {
if (const auto *sExpr{UnwrapExpr<Expr<SomeReal>>(args[1])}) {
- return std::visit(
+ return common::visit(
[&](const auto &sVal) {
using TS = ResultType<decltype(sVal)>;
return FoldElementalIntrinsic<T, T, TS>(context, std::move(funcRef),
@@ -158,7 +158,7 @@ Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction(
}
} else if (name == "scale") {
if (const auto *byExpr{UnwrapExpr<Expr<SomeInteger>>(args[1])}) {
- return std::visit(
+ return common::visit(
[&](const auto &byVal) {
using TBY = ResultType<decltype(byVal)>;
return FoldElementalIntrinsic<T, T, TBY>(context,
@@ -194,7 +194,7 @@ Expr<Type<TypeCategory::Real, KIND>> FoldIntrinsicFunction(
return Expr<T>{Scalar<T>::TINY()};
} else if (name == "__builtin_ieee_next_after") {
if (const auto *yExpr{UnwrapExpr<Expr<SomeReal>>(args[1])}) {
- return std::visit(
+ return common::visit(
[&](const auto &yVal) {
using TY = ResultType<decltype(yVal)>;
return FoldElementalIntrinsic<T, T, TY>(context, std::move(funcRef),
diff --git a/flang/lib/Evaluate/fold.cpp b/flang/lib/Evaluate/fold.cpp
index f3c2e6ca1c563..ae8b586f47175 100644
--- a/flang/lib/Evaluate/fold.cpp
+++ b/flang/lib/Evaluate/fold.cpp
@@ -21,7 +21,7 @@ characteristics::TypeAndShape Fold(
std::optional<Constant<SubscriptInteger>> GetConstantSubscript(
FoldingContext &context, Subscript &ss, const NamedEntity &base, int dim) {
ss = FoldOperation(context, std::move(ss));
- return std::visit(
+ return common::visit(
common::visitors{
[](IndirectSubscriptIntegerExpr &expr)
-> std::optional<Constant<SubscriptInteger>> {
@@ -119,16 +119,16 @@ Triplet FoldOperation(FoldingContext &context, Triplet &&triplet) {
}
Subscript FoldOperation(FoldingContext &context, Subscript &&subscript) {
- return std::visit(common::visitors{
- [&](IndirectSubscriptIntegerExpr &&expr) {
- expr.value() = Fold(context, std::move(expr.value()));
- return Subscript(std::move(expr));
- },
- [&](Triplet &&triplet) {
- return Subscript(
- FoldOperation(context, std::move(triplet)));
- },
- },
+ return common::visit(
+ common::visitors{
+ [&](IndirectSubscriptIntegerExpr &&expr) {
+ expr.value() = Fold(context, std::move(expr.value()));
+ return Subscript(std::move(expr));
+ },
+ [&](Triplet &&triplet) {
+ return Subscript(FoldOperation(context, std::move(triplet)));
+ },
+ },
std::move(subscript.u));
}
@@ -162,12 +162,13 @@ CoarrayRef FoldOperation(FoldingContext &context, CoarrayRef &&coarrayRef) {
}
DataRef FoldOperation(FoldingContext &context, DataRef &&dataRef) {
- return std::visit(common::visitors{
- [&](SymbolRef symbol) { return DataRef{*symbol}; },
- [&](auto &&x) {
- return DataRef{FoldOperation(context, std::move(x))};
- },
- },
+ return common::visit(common::visitors{
+ [&](SymbolRef symbol) { return DataRef{*symbol}; },
+ [&](auto &&x) {
+ return DataRef{
+ FoldOperation(context, std::move(x))};
+ },
+ },
std::move(dataRef.u));
}
diff --git a/flang/lib/Evaluate/formatting.cpp b/flang/lib/Evaluate/formatting.cpp
index e5b44779100e3..646d4bc5b2f7c 100644
--- a/flang/lib/Evaluate/formatting.cpp
+++ b/flang/lib/Evaluate/formatting.cpp
@@ -111,7 +111,7 @@ llvm::raw_ostream &ActualArgument::AsFortran(llvm::raw_ostream &o) const {
if (keyword_) {
o << keyword_->ToString() << '=';
}
- std::visit(
+ common::visit(
common::visitors{
[&](const common::CopyableIndirection<Expr<SomeType>> &expr) {
expr.value().AsFortran(o);
@@ -227,7 +227,7 @@ template <typename T> static Precedence ToPrecedence(const Constant<T> &x) {
return Precedence::Top;
}
template <typename T> static Precedence ToPrecedence(const Expr<T> &expr) {
- return std::visit([](const auto &x) { return ToPrecedence(x); }, expr.u);
+ return common::visit([](const auto &x) { return ToPrecedence(x); }, expr.u);
}
template <typename T> static bool IsNegatedScalarConstant(const Expr<T> &expr) {
@@ -242,7 +242,7 @@ template <typename T> static bool IsNegatedScalarConstant(const Expr<T> &expr) {
template <TypeCategory CAT>
static bool IsNegatedScalarConstant(const Expr<SomeKind<CAT>> &expr) {
- return std::visit(
+ return common::visit(
[](const auto &x) { return IsNegatedScalarConstant(x); }, expr.u);
}
@@ -373,7 +373,7 @@ llvm::raw_ostream &Convert<TO, FROMCAT>::AsFortran(llvm::raw_ostream &o) const {
}
llvm::raw_ostream &Relational<SomeType>::AsFortran(llvm::raw_ostream &o) const {
- std::visit([&](const auto &rel) { rel.AsFortran(o); }, u);
+ common::visit([&](const auto &rel) { rel.AsFortran(o); }, u);
return o;
}
@@ -404,7 +404,7 @@ llvm::raw_ostream &EmitArray(
const char *sep{""};
for (const auto &value : values) {
o << sep;
- std::visit([&](const auto &x) { EmitArray(o, x); }, value.u);
+ common::visit([&](const auto &x) { EmitArray(o, x); }, value.u);
sep = ",";
}
return o;
@@ -444,17 +444,17 @@ std::string ExpressionBase<RESULT>::AsFortran() const {
template <typename RESULT>
llvm::raw_ostream &ExpressionBase<RESULT>::AsFortran(
llvm::raw_ostream &o) const {
- std::visit(common::visitors{
- [&](const BOZLiteralConstant &x) {
- o << "z'" << x.Hexadecimal() << "'";
- },
- [&](const NullPointer &) { o << "NULL()"; },
- [&](const common::CopyableIndirection<Substring> &s) {
- s.value().AsFortran(o);
- },
- [&](const ImpliedDoIndex &i) { o << i.name.ToString(); },
- [&](const auto &x) { x.AsFortran(o); },
- },
+ common::visit(common::visitors{
+ [&](const BOZLiteralConstant &x) {
+ o << "z'" << x.Hexadecimal() << "'";
+ },
+ [&](const NullPointer &) { o << "NULL()"; },
+ [&](const common::CopyableIndirection<Substring> &s) {
+ s.value().AsFortran(o);
+ },
+ [&](const ImpliedDoIndex &i) { o << i.name.ToString(); },
+ [&](const auto &x) { x.AsFortran(o); },
+ },
derived().u);
return o;
}
@@ -608,7 +608,7 @@ llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::shared_ptr<A> &p) {
template <typename... A>
llvm::raw_ostream &EmitVar(llvm::raw_ostream &o, const std::variant<A...> &u) {
- std::visit([&](const auto &x) { EmitVar(o, x); }, u);
+ common::visit([&](const auto &x) { EmitVar(o, x); }, u);
return o;
}
@@ -629,10 +629,10 @@ llvm::raw_ostream &Component::AsFortran(llvm::raw_ostream &o) const {
}
llvm::raw_ostream &NamedEntity::AsFortran(llvm::raw_ostream &o) const {
- std::visit(common::visitors{
- [&](SymbolRef s) { EmitVar(o, s); },
- [&](const Component &c) { c.AsFortran(o); },
- },
+ common::visit(common::visitors{
+ [&](SymbolRef s) { EmitVar(o, s); },
+ [&](const Component &c) { c.AsFortran(o); },
+ },
u_);
return o;
}
@@ -712,10 +712,10 @@ llvm::raw_ostream &ProcedureDesignator::AsFortran(llvm::raw_ostream &o) const {
template <typename T>
llvm::raw_ostream &Designator<T>::AsFortran(llvm::raw_ostream &o) const {
- std::visit(common::visitors{
- [&](SymbolRef symbol) { EmitVar(o, symbol); },
- [&](const auto &x) { x.AsFortran(o); },
- },
+ common::visit(common::visitors{
+ [&](SymbolRef symbol) { EmitVar(o, symbol); },
+ [&](const auto &x) { x.AsFortran(o); },
+ },
u);
return o;
}
@@ -752,7 +752,7 @@ llvm::raw_ostream &DescriptorInquiry::AsFortran(llvm::raw_ostream &o) const {
}
llvm::raw_ostream &Assignment::AsFortran(llvm::raw_ostream &o) const {
- std::visit(
+ common::visit(
common::visitors{
[&](const Assignment::Intrinsic &) {
rhs.AsFortran(lhs.AsFortran(o) << '=');
diff --git a/flang/lib/Evaluate/shape.cpp b/flang/lib/Evaluate/shape.cpp
index a10295236df61..b7930cd663936 100644
--- a/flang/lib/Evaluate/shape.cpp
+++ b/flang/lib/Evaluate/shape.cpp
@@ -480,7 +480,7 @@ MaybeExtentExpr GetExtent(
MaybeExtentExpr GetExtent(
const Subscript &subscript, const NamedEntity &base, int dimension) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const Triplet &triplet) -> MaybeExtentExpr {
MaybeExtentExpr upper{triplet.upper()};
@@ -650,7 +650,7 @@ Shape GetUBOUNDs(FoldingContext &context, const NamedEntity &base) {
Shape GetUBOUNDs(const NamedEntity &base) { return GetUBOUNDs(nullptr, base); }
auto GetShapeHelper::operator()(const Symbol &symbol) const -> Result {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const semantics::ObjectEntityDetails &object) {
if (IsImpliedShape(symbol) && object.init()) {
diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index 5db7d1f0d4e2f..6fee72ae84195 100644
--- a/flang/lib/Evaluate/tools.cpp
+++ b/flang/lib/Evaluate/tools.cpp
@@ -40,7 +40,7 @@ std::optional<Expr<SomeType>> AsGenericExpr(const Symbol &symbol) {
}
Expr<SomeType> Parenthesize(Expr<SomeType> &&expr) {
- return std::visit(
+ return common::visit(
[&](auto &&x) {
using T = std::decay_t<decltype(x)>;
if constexpr (common::HasMember<T, TypelessExpression>) {
@@ -48,7 +48,7 @@ Expr<SomeType> Parenthesize(Expr<SomeType> &&expr) {
} else if constexpr (std::is_same_v<T, Expr<SomeDerived>>) {
return AsGenericExpr(Parentheses<SomeDerived>{std::move(x)});
} else {
- return std::visit(
+ return common::visit(
[](auto &&y) {
using T = ResultType<decltype(y)>;
return AsGenericExpr(Parentheses<T>{std::move(y)});
@@ -69,7 +69,7 @@ std::optional<DataRef> ExtractDataRef(
}
std::optional<DataRef> ExtractSubstringBase(const Substring &substring) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const DataRef &x) -> std::optional<DataRef> { return x; },
[&](const StaticDataObject::Pointer &) -> std::optional<DataRef> {
@@ -108,7 +108,7 @@ auto IsVariableHelper::operator()(const ProcedureDesignator &x) const
ConvertRealOperandsResult ConvertRealOperands(
parser::ContextualMessages &messages, Expr<SomeType> &&x,
Expr<SomeType> &&y, int defaultRealKind) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](Expr<SomeInteger> &&ix,
Expr<SomeInteger> &&iy) -> ConvertRealOperandsResult {
@@ -190,7 +190,7 @@ std::optional<Expr<SomeType>> Package(
template <template <typename> class OPR>
std::optional<Expr<SomeType>> MixedRealLeft(
Expr<SomeReal> &&rx, Expr<SomeInteger> &&iy) {
- return Package(std::visit(
+ return Package(common::visit(
[&](auto &&rxk) -> Expr<SomeReal> {
using resultType = ResultType<decltype(rxk)>;
if constexpr (std::is_same_v<OPR<resultType>, Power<resultType>>) {
@@ -210,7 +210,7 @@ std::optional<Expr<SomeComplex>> ConstructComplex(
Expr<SomeType> &&imaginary, int defaultRealKind) {
if (auto converted{ConvertRealOperands(
messages, std::move(real), std::move(imaginary), defaultRealKind)}) {
- return {std::visit(
+ return {common::visit(
[](auto &&pair) {
return MakeComplex(std::move(pair[0]), std::move(pair[1]));
},
@@ -230,7 +230,7 @@ std::optional<Expr<SomeComplex>> ConstructComplex(
}
Expr<SomeReal> GetComplexPart(const Expr<SomeComplex> &z, bool isImaginary) {
- return std::visit(
+ return common::visit(
[&](const auto &zk) {
static constexpr int kind{ResultType<decltype(zk)>::kind};
return AsCategoryExpr(ComplexComponent<kind>{isImaginary, zk});
@@ -243,7 +243,7 @@ Expr<SomeReal> GetComplexPart(const Expr<SomeComplex> &z, bool isImaginary) {
// the highest precision of REAL and COMPLEX operands as required by Fortran
// 2018 10.9.1.3.
Expr<SomeComplex> PromoteRealToComplex(Expr<SomeReal> &&someX) {
- return std::visit(
+ return common::visit(
[](auto &&x) {
using RT = ResultType<decltype(x)>;
return AsCategoryExpr(ComplexConstructor<RT::kind>{
@@ -289,7 +289,7 @@ std::optional<Expr<SomeType>> MixedComplexLeft(
std::is_same_v<OPR<LargestReal>, Power<LargestReal>>) {
// COMPLEX**INTEGER is a special case that doesn't convert the exponent.
static_assert(RCAT == TypeCategory::Integer);
- return Package(std::visit(
+ return Package(common::visit(
[&](auto &&zxk) {
using Ty = ResultType<decltype(zxk)>;
return AsCategoryExpr(
@@ -358,7 +358,7 @@ template <template <typename> class OPR>
std::optional<Expr<SomeType>> NumericOperation(
parser::ContextualMessages &messages, Expr<SomeType> &&x,
Expr<SomeType> &&y, int defaultRealKind) {
- return std::visit(
+ return common::visit(
common::visitors{
[](Expr<SomeInteger> &&ix, Expr<SomeInteger> &&iy) {
return Package(PromoteAndCombine<OPR, TypeCategory::Integer>(
@@ -373,7 +373,7 @@ std::optional<Expr<SomeType>> NumericOperation(
return MixedRealLeft<OPR>(std::move(rx), std::move(iy));
},
[](Expr<SomeInteger> &&ix, Expr<SomeReal> &&ry) {
- return Package(std::visit(
+ return Package(common::visit(
[&](auto &&ryk) -> Expr<SomeReal> {
using resultType = ResultType<decltype(ryk)>;
return AsCategoryExpr(
@@ -450,7 +450,7 @@ template std::optional<Expr<SomeType>> NumericOperation<Subtract>(
std::optional<Expr<SomeType>> Negation(
parser::ContextualMessages &messages, Expr<SomeType> &&x) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](BOZLiteralConstant &&) {
messages.Say("BOZ literal cannot be negated"_err_en_US);
@@ -491,7 +491,7 @@ std::optional<Expr<SomeType>> Negation(
}
Expr<SomeLogical> LogicalNegation(Expr<SomeLogical> &&x) {
- return std::visit(
+ return common::visit(
[](auto &&xk) { return AsCategoryExpr(LogicalNegation(std::move(xk))); },
std::move(x.u));
}
@@ -499,7 +499,7 @@ Expr<SomeLogical> LogicalNegation(Expr<SomeLogical> &&x) {
template <TypeCategory CAT>
Expr<LogicalResult> PromoteAndRelate(
RelationalOperator opr, Expr<SomeKind<CAT>> &&x, Expr<SomeKind<CAT>> &&y) {
- return std::visit(
+ return common::visit(
[=](auto &&xy) {
return PackageRelation(opr, std::move(xy[0]), std::move(xy[1]));
},
@@ -508,7 +508,7 @@ Expr<LogicalResult> PromoteAndRelate(
std::optional<Expr<LogicalResult>> Relate(parser::ContextualMessages &messages,
RelationalOperator opr, Expr<SomeType> &&x, Expr<SomeType> &&y) {
- return std::visit(
+ return common::visit(
common::visitors{
[=](Expr<SomeInteger> &&ix,
Expr<SomeInteger> &&iy) -> std::optional<Expr<LogicalResult>> {
@@ -554,7 +554,7 @@ std::optional<Expr<LogicalResult>> Relate(parser::ContextualMessages &messages,
AsGenericExpr(ConvertTo(zy, std::move(rx))), std::move(y));
},
[&](Expr<SomeCharacter> &&cx, Expr<SomeCharacter> &&cy) {
- return std::visit(
+ return common::visit(
[&](auto &&cxk,
auto &&cyk) -> std::optional<Expr<LogicalResult>> {
using Ty = ResultType<decltype(cxk)>;
@@ -580,7 +580,7 @@ std::optional<Expr<LogicalResult>> Relate(parser::ContextualMessages &messages,
Expr<SomeLogical> BinaryLogicalOperation(
LogicalOperator opr, Expr<SomeLogical> &&x, Expr<SomeLogical> &&y) {
CHECK(opr != LogicalOperator::Not);
- return std::visit(
+ return common::visit(
[=](auto &&xy) {
using Ty = ResultType<decltype(xy[0])>;
return Expr<SomeLogical>{BinaryLogicalOperation<Ty::kind>(
@@ -592,7 +592,7 @@ Expr<SomeLogical> BinaryLogicalOperation(
template <TypeCategory TO>
std::optional<Expr<SomeType>> ConvertToNumeric(int kind, Expr<SomeType> &&x) {
static_assert(common::IsNumericTypeCategory(TO));
- return std::visit(
+ return common::visit(
[=](auto &&cx) -> std::optional<Expr<SomeType>> {
using cxType = std::decay_t<decltype(cx)>;
if constexpr (!common::HasMember<cxType, TypelessExpression>) {
@@ -632,7 +632,7 @@ std::optional<Expr<SomeType>> ConvertToType(
auto converted{
ConvertToKind<TypeCategory::Character>(type.kind(), std::move(*cx))};
if (auto length{type.GetCharLength()}) {
- converted = std::visit(
+ converted = common::visit(
[&](auto &&x) {
using Ty = std::decay_t<decltype(x)>;
using CharacterType = typename Ty::Result;
@@ -732,15 +732,15 @@ bool IsFunction(const Expr<SomeType> &expr) {
}
bool IsProcedurePointerTarget(const Expr<SomeType> &expr) {
- return std::visit(common::visitors{
- [](const NullPointer &) { return true; },
- [](const ProcedureDesignator &) { return true; },
- [](const ProcedureRef &) { return true; },
- [&](const auto &) {
- const Symbol *last{GetLastSymbol(expr)};
- return last && IsProcedurePointer(*last);
- },
- },
+ return common::visit(common::visitors{
+ [](const NullPointer &) { return true; },
+ [](const ProcedureDesignator &) { return true; },
+ [](const ProcedureRef &) { return true; },
+ [&](const auto &) {
+ const Symbol *last{GetLastSymbol(expr)};
+ return last && IsProcedurePointer(*last);
+ },
+ },
expr.u);
}
@@ -755,7 +755,7 @@ inline const ProcedureRef *UnwrapProcedureRef(const FunctionRef<T> &func) {
template <typename T>
inline const ProcedureRef *UnwrapProcedureRef(const Expr<T> &expr) {
- return std::visit(
+ return common::visit(
[](const auto &x) { return UnwrapProcedureRef(x); }, expr.u);
}
@@ -792,7 +792,7 @@ struct IsNullPointerHelper {
return (*this)(x.left());
}
template <typename T> bool operator()(const Expr<T> &x) const {
- return std::visit(*this, x.u);
+ return common::visit(*this, x.u);
}
};
@@ -1019,7 +1019,8 @@ static const Symbol *GetLastPointerSymbol(const CoarrayRef &x) {
return nullptr;
}
const Symbol *GetLastPointerSymbol(const DataRef &x) {
- return std::visit([](const auto &y) { return GetLastPointerSymbol(y); }, x.u);
+ return common::visit(
+ [](const auto &y) { return GetLastPointerSymbol(y); }, x.u);
}
template <TypeCategory TO, TypeCategory FROM>
@@ -1030,7 +1031,7 @@ static std::optional<Expr<SomeType>> DataConstantConversionHelper(
if (auto sized{
Fold(context, ConvertToType(sizedType, Expr<SomeType>{expr}))}) {
if (const auto *someExpr{UnwrapExpr<Expr<SomeKind<FROM>>>(*sized)}) {
- return std::visit(
+ return common::visit(
[](const auto &w) -> std::optional<Expr<SomeType>> {
using FromType = typename std::decay_t<decltype(w)>::Result;
static constexpr int kind{FromType::kind};
@@ -1219,18 +1220,19 @@ bool IsPureProcedure(const Scope &scope) {
bool IsFunction(const Symbol &symbol) {
const Symbol &ultimate{symbol.GetUltimate()};
return ultimate.test(Symbol::Flag::Function) ||
- std::visit(common::visitors{
- [](const SubprogramDetails &x) { return x.isFunction(); },
- [](const ProcEntityDetails &x) {
- const auto &ifc{x.interface()};
- return ifc.type() ||
- (ifc.symbol() && IsFunction(*ifc.symbol()));
- },
- [](const ProcBindingDetails &x) {
- return IsFunction(x.symbol());
- },
- [](const auto &) { return false; },
- },
+ common::visit(
+ common::visitors{
+ [](const SubprogramDetails &x) { return x.isFunction(); },
+ [](const ProcEntityDetails &x) {
+ const auto &ifc{x.interface()};
+ return ifc.type() ||
+ (ifc.symbol() && IsFunction(*ifc.symbol()));
+ },
+ [](const ProcBindingDetails &x) {
+ return IsFunction(x.symbol());
+ },
+ [](const auto &) { return false; },
+ },
ultimate.details());
}
@@ -1240,14 +1242,14 @@ bool IsFunction(const Scope &scope) {
}
bool IsProcedure(const Symbol &symbol) {
- return std::visit(common::visitors{
- [](const SubprogramDetails &) { return true; },
- [](const SubprogramNameDetails &) { return true; },
- [](const ProcEntityDetails &) { return true; },
- [](const GenericDetails &) { return true; },
- [](const ProcBindingDetails &) { return true; },
- [](const auto &) { return false; },
- },
+ return common::visit(common::visitors{
+ [](const SubprogramDetails &) { return true; },
+ [](const SubprogramNameDetails &) { return true; },
+ [](const ProcEntityDetails &) { return true; },
+ [](const GenericDetails &) { return true; },
+ [](const ProcBindingDetails &) { return true; },
+ [](const auto &) { return false; },
+ },
symbol.GetUltimate().details());
}
@@ -1361,7 +1363,7 @@ bool IsSaved(const Symbol &original) {
}
bool IsDummy(const Symbol &symbol) {
- return std::visit(
+ return common::visit(
common::visitors{[](const EntityDetails &x) { return x.isDummy(); },
[](const ObjectEntityDetails &x) { return x.isDummy(); },
[](const ProcEntityDetails &x) { return x.isDummy(); },
@@ -1490,7 +1492,7 @@ static const Symbol *FindFunctionResult(
if (!seen.insert(root).second) {
return nullptr; // don't loop
}
- return std::visit(
+ return common::visit(
common::visitors{[](const SubprogramDetails &subp) {
return subp.isFunction() ? &subp.result() : nullptr;
},
diff --git a/flang/lib/Evaluate/type.cpp b/flang/lib/Evaluate/type.cpp
index 22ea3ea27ad29..3ccb25b94010e 100644
--- a/flang/lib/Evaluate/type.cpp
+++ b/flang/lib/Evaluate/type.cpp
@@ -55,7 +55,7 @@ static bool IsDescriptor(const ProcEntityDetails &details) {
}
bool IsDescriptor(const Symbol &symbol) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const ObjectEntityDetails &d) {
return IsAllocatableOrPointer(symbol) || IsDescriptor(d);
diff --git a/flang/lib/Evaluate/variable.cpp b/flang/lib/Evaluate/variable.cpp
index 4788fc50e0759..b19effa980233 100644
--- a/flang/lib/Evaluate/variable.cpp
+++ b/flang/lib/Evaluate/variable.cpp
@@ -145,7 +145,7 @@ std::optional<Expr<SubscriptInteger>> Substring::upper() const {
if (upper_) {
return upper_.value().value();
} else {
- return std::visit(
+ return common::visit(
common::visitors{
[](const DataRef &dataRef) { return dataRef.LEN(); },
[](const StaticDataObject::Pointer &object)
@@ -208,7 +208,7 @@ std::optional<Expr<SomeCharacter>> Substring::Fold(FoldingContext &context) {
}
std::optional<Expr<SomeCharacter>> result;
if (strings) {
- result = std::visit(
+ result = common::visit(
[&](const auto &expr) -> std::optional<Expr<SomeCharacter>> {
using Type = typename std::decay_t<decltype(expr)>::Result;
if (const auto *cc{std::get_if<Constant<Type>>(&expr.u)}) {
@@ -281,7 +281,7 @@ static std::optional<Expr<SubscriptInteger>> SymbolLEN(const Symbol &symbol) {
}
std::optional<Expr<SubscriptInteger>> BaseObject::LEN() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](const Symbol &symbol) { return SymbolLEN(symbol); },
[](const StaticDataObject::Pointer &object)
@@ -309,10 +309,10 @@ std::optional<Expr<SubscriptInteger>> CoarrayRef::LEN() const {
}
std::optional<Expr<SubscriptInteger>> DataRef::LEN() const {
- return std::visit(common::visitors{
- [](SymbolRef symbol) { return SymbolLEN(symbol); },
- [](const auto &x) { return x.LEN(); },
- },
+ return common::visit(common::visitors{
+ [](SymbolRef symbol) { return SymbolLEN(symbol); },
+ [](const auto &x) { return x.LEN(); },
+ },
u);
}
@@ -329,10 +329,10 @@ std::optional<Expr<SubscriptInteger>> Substring::LEN() const {
template <typename T>
std::optional<Expr<SubscriptInteger>> Designator<T>::LEN() const {
if constexpr (T::category == TypeCategory::Character) {
- return std::visit(common::visitors{
- [](SymbolRef symbol) { return SymbolLEN(symbol); },
- [](const auto &x) { return x.LEN(); },
- },
+ return common::visit(common::visitors{
+ [](SymbolRef symbol) { return SymbolLEN(symbol); },
+ [](const auto &x) { return x.LEN(); },
+ },
u);
} else {
common::die("Designator<non-char>::LEN() called");
@@ -342,7 +342,7 @@ std::optional<Expr<SubscriptInteger>> Designator<T>::LEN() const {
std::optional<Expr<SubscriptInteger>> ProcedureDesignator::LEN() const {
using T = std::optional<Expr<SubscriptInteger>>;
- return std::visit(
+ return common::visit(
common::visitors{
[](SymbolRef symbol) -> T { return SymbolLEN(symbol); },
[](const common::CopyableIndirection<Component> &c) -> T {
@@ -367,10 +367,10 @@ std::optional<Expr<SubscriptInteger>> ProcedureDesignator::LEN() const {
// Rank()
int BaseObject::Rank() const {
- return std::visit(common::visitors{
- [](SymbolRef symbol) { return symbol->Rank(); },
- [](const StaticDataObject::Pointer &) { return 0; },
- },
+ return common::visit(common::visitors{
+ [](SymbolRef symbol) { return symbol->Rank(); },
+ [](const StaticDataObject::Pointer &) { return 0; },
+ },
u);
}
@@ -382,20 +382,20 @@ int Component::Rank() const {
}
int NamedEntity::Rank() const {
- return std::visit(common::visitors{
- [](const SymbolRef s) { return s->Rank(); },
- [](const Component &c) { return c.Rank(); },
- },
+ return common::visit(common::visitors{
+ [](const SymbolRef s) { return s->Rank(); },
+ [](const Component &c) { return c.Rank(); },
+ },
u_);
}
int Subscript::Rank() const {
- return std::visit(common::visitors{
- [](const IndirectSubscriptIntegerExpr &x) {
- return x.value().Rank();
- },
- [](const Triplet &) { return 1; },
- },
+ return common::visit(common::visitors{
+ [](const IndirectSubscriptIntegerExpr &x) {
+ return x.value().Rank();
+ },
+ [](const Triplet &) { return 1; },
+ },
u);
}
@@ -426,28 +426,29 @@ int CoarrayRef::Rank() const {
}
int DataRef::Rank() const {
- return std::visit(common::visitors{
- [](SymbolRef symbol) { return symbol->Rank(); },
- [](const auto &x) { return x.Rank(); },
- },
+ return common::visit(common::visitors{
+ [](SymbolRef symbol) { return symbol->Rank(); },
+ [](const auto &x) { return x.Rank(); },
+ },
u);
}
int Substring::Rank() const {
- return std::visit(common::visitors{
- [](const DataRef &dataRef) { return dataRef.Rank(); },
- [](const StaticDataObject::Pointer &) { return 0; },
- },
+ return common::visit(
+ common::visitors{
+ [](const DataRef &dataRef) { return dataRef.Rank(); },
+ [](const StaticDataObject::Pointer &) { return 0; },
+ },
parent_);
}
int ComplexPart::Rank() const { return complex_.Rank(); }
template <typename T> int Designator<T>::Rank() const {
- return std::visit(common::visitors{
- [](SymbolRef symbol) { return symbol->Rank(); },
- [](const auto &x) { return x.Rank(); },
- },
+ return common::visit(common::visitors{
+ [](SymbolRef symbol) { return symbol->Rank(); },
+ [](const auto &x) { return x.Rank(); },
+ },
u);
}
@@ -457,38 +458,39 @@ const Symbol &Component::GetFirstSymbol() const {
}
const Symbol &NamedEntity::GetFirstSymbol() const {
- return std::visit(common::visitors{
- [](SymbolRef s) -> const Symbol & { return s; },
- [](const Component &c) -> const Symbol & {
- return c.GetFirstSymbol();
- },
- },
+ return common::visit(common::visitors{
+ [](SymbolRef s) -> const Symbol & { return s; },
+ [](const Component &c) -> const Symbol & {
+ return c.GetFirstSymbol();
+ },
+ },
u_);
}
const Symbol &NamedEntity::GetLastSymbol() const {
- return std::visit(common::visitors{
- [](SymbolRef s) -> const Symbol & { return s; },
- [](const Component &c) -> const Symbol & {
- return c.GetLastSymbol();
- },
- },
+ return common::visit(common::visitors{
+ [](SymbolRef s) -> const Symbol & { return s; },
+ [](const Component &c) -> const Symbol & {
+ return c.GetLastSymbol();
+ },
+ },
u_);
}
const Component *NamedEntity::UnwrapComponent() const {
- return std::visit(common::visitors{
- [](SymbolRef) -> const Component * { return nullptr; },
- [](const Component &c) { return &c; },
- },
+ return common::visit(
+ common::visitors{
+ [](SymbolRef) -> const Component * { return nullptr; },
+ [](const Component &c) { return &c; },
+ },
u_);
}
Component *NamedEntity::UnwrapComponent() {
- return std::visit(common::visitors{
- [](SymbolRef &) -> Component * { return nullptr; },
- [](Component &c) { return &c; },
- },
+ return common::visit(common::visitors{
+ [](SymbolRef &) -> Component * { return nullptr; },
+ [](Component &c) { return &c; },
+ },
u_);
}
@@ -499,35 +501,35 @@ const Symbol &ArrayRef::GetFirstSymbol() const {
const Symbol &ArrayRef::GetLastSymbol() const { return base_.GetLastSymbol(); }
const Symbol &DataRef::GetFirstSymbol() const {
- return *std::visit(common::visitors{
- [](SymbolRef symbol) { return &*symbol; },
- [](const auto &x) { return &x.GetFirstSymbol(); },
- },
+ return *common::visit(common::visitors{
+ [](SymbolRef symbol) { return &*symbol; },
+ [](const auto &x) { return &x.GetFirstSymbol(); },
+ },
u);
}
const Symbol &DataRef::GetLastSymbol() const {
- return *std::visit(common::visitors{
- [](SymbolRef symbol) { return &*symbol; },
- [](const auto &x) { return &x.GetLastSymbol(); },
- },
+ return *common::visit(common::visitors{
+ [](SymbolRef symbol) { return &*symbol; },
+ [](const auto &x) { return &x.GetLastSymbol(); },
+ },
u);
}
BaseObject Substring::GetBaseObject() const {
- return std::visit(common::visitors{
- [](const DataRef &dataRef) {
- return BaseObject{dataRef.GetFirstSymbol()};
- },
- [](StaticDataObject::Pointer pointer) {
- return BaseObject{std::move(pointer)};
- },
- },
+ return common::visit(common::visitors{
+ [](const DataRef &dataRef) {
+ return BaseObject{dataRef.GetFirstSymbol()};
+ },
+ [](StaticDataObject::Pointer pointer) {
+ return BaseObject{std::move(pointer)};
+ },
+ },
parent_);
}
const Symbol *Substring::GetLastSymbol() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](const DataRef &dataRef) { return &dataRef.GetLastSymbol(); },
[](const auto &) -> const Symbol * { return nullptr; },
@@ -536,7 +538,7 @@ const Symbol *Substring::GetLastSymbol() const {
}
template <typename T> BaseObject Designator<T>::GetBaseObject() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](SymbolRef symbol) { return BaseObject{symbol}; },
[](const Substring &sstring) { return sstring.GetBaseObject(); },
@@ -554,7 +556,7 @@ template <typename T> BaseObject Designator<T>::GetBaseObject() const {
}
template <typename T> const Symbol *Designator<T>::GetLastSymbol() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](SymbolRef symbol) { return &*symbol; },
[](const Substring &sstring) { return sstring.GetLastSymbol(); },
diff --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp
index 522101f9c2300..18e6b3784be3e 100644
--- a/flang/lib/Parser/message.cpp
+++ b/flang/lib/Parser/message.cpp
@@ -85,7 +85,7 @@ const char *MessageFormattedText::Convert(CharBlock x) {
}
std::string MessageExpectedText::ToString() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](CharBlock cb) {
return MessageFormattedText("expected '%s'"_err_en_US, cb)
@@ -124,13 +124,13 @@ std::string MessageExpectedText::ToString() const {
}
bool MessageExpectedText::Merge(const MessageExpectedText &that) {
- return std::visit(common::visitors{
- [](SetOfChars &s1, const SetOfChars &s2) {
- s1 = s1.Union(s2);
- return true;
- },
- [](const auto &, const auto &) { return false; },
- },
+ return common::visit(common::visitors{
+ [](SetOfChars &s1, const SetOfChars &s2) {
+ s1 = s1.Union(s2);
+ return true;
+ },
+ [](const auto &, const auto &) { return false; },
+ },
u_, that.u_);
}
@@ -141,7 +141,7 @@ bool Message::SortBefore(const Message &that) const {
// free and needs to be deferred, and many messages created during parsing
// are speculative. Messages with ProvenanceRange locations are ordered
// before others for sorting.
- return std::visit(
+ return common::visit(
common::visitors{
[](CharBlock cb1, CharBlock cb2) {
return cb1.begin() < cb2.begin();
@@ -158,7 +158,7 @@ bool Message::SortBefore(const Message &that) const {
bool Message::IsFatal() const { return severity() == Severity::Error; }
Severity Message::severity() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](const MessageExpectedText &) { return Severity::Error; },
[](const MessageFixedText &x) { return x.severity(); },
@@ -168,7 +168,7 @@ Severity Message::severity() const {
}
Message &Message::set_severity(Severity severity) {
- std::visit(
+ common::visit(
common::visitors{
[](const MessageExpectedText &) {},
[severity](MessageFixedText &x) { x.set_severity(severity); },
@@ -179,7 +179,7 @@ Message &Message::set_severity(Severity severity) {
}
std::string Message::ToString() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](const MessageFixedText &t) {
return t.text().NULTerminatedToString();
@@ -204,7 +204,7 @@ void Message::ResolveProvenances(const AllCookedSources &allCooked) {
std::optional<ProvenanceRange> Message::GetProvenanceRange(
const AllCookedSources &allCooked) const {
- return std::visit(
+ return common::visit(
common::visitors{
[&](CharBlock cb) { return allCooked.GetProvenanceRange(cb); },
[](const ProvenanceRange &pr) { return std::make_optional(pr); },
@@ -271,7 +271,7 @@ bool Message::Merge(const Message &that) {
return AtSameLocation(that) &&
(!that.attachment_.get() ||
attachment_.get() == that.attachment_.get()) &&
- std::visit(
+ common::visit(
common::visitors{
[](MessageExpectedText &e1, const MessageExpectedText &e2) {
return e1.Merge(e2);
@@ -299,7 +299,7 @@ Message &Message::Attach(std::unique_ptr<Message> &&m) {
}
bool Message::AtSameLocation(const Message &that) const {
- return std::visit(
+ return common::visit(
common::visitors{
[](CharBlock cb1, CharBlock cb2) {
return cb1.begin() == cb2.begin();
diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp
index b81a659364f06..4edb3c67ba92b 100644
--- a/flang/lib/Parser/parse-tree.cpp
+++ b/flang/lib/Parser/parse-tree.cpp
@@ -32,7 +32,7 @@ CommonStmt::CommonStmt(std::optional<Name> &&name,
// R901 designator
bool Designator::EndsInBareName() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](const DataRef &dr) {
return std::holds_alternative<Name>(dr.u) ||
@@ -120,11 +120,11 @@ template <typename T> T WithSource(CharBlock source, T &&x) {
}
static Expr ActualArgToExpr(ActualArgSpec &arg) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](common::Indirection<Expr> &y) { return std::move(y.value()); },
[&](common::Indirection<Variable> &y) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](common::Indirection<Designator> &z) {
return WithSource(
@@ -147,7 +147,7 @@ Designator FunctionReference::ConvertToArrayElementRef() {
for (auto &arg : std::get<std::list<ActualArgSpec>>(v.t)) {
args.emplace_back(ActualArgToExpr(arg));
}
- return std::visit(
+ return common::visit(
common::visitors{
[&](const Name &name) {
return WithSource(
@@ -231,7 +231,7 @@ Statement<ActionStmt> StmtFunctionStmt::ConvertToAssignment() {
}
CharBlock Variable::GetSource() const {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const common::Indirection<Designator> &des) {
return des.value().source;
diff --git a/flang/lib/Parser/provenance.cpp b/flang/lib/Parser/provenance.cpp
index e2364d3f8a562..a46111c6b1a8b 100644
--- a/flang/lib/Parser/provenance.cpp
+++ b/flang/lib/Parser/provenance.cpp
@@ -232,7 +232,7 @@ void AllSources::EmitMessage(llvm::raw_ostream &o,
}
CHECK(IsValid(*range));
const Origin &origin{MapToOrigin(range->start())};
- std::visit(
+ common::visit(
common::visitors{
[&](const Inclusion &inc) {
o << inc.source.path();
@@ -294,23 +294,24 @@ void AllSources::EmitMessage(llvm::raw_ostream &o,
const SourceFile *AllSources::GetSourceFile(
Provenance at, std::size_t *offset) const {
const Origin &origin{MapToOrigin(at)};
- return std::visit(common::visitors{
- [&](const Inclusion &inc) {
- if (offset) {
- *offset = origin.covers.MemberOffset(at);
- }
- return &inc.source;
- },
- [&](const Macro &) {
- return GetSourceFile(origin.replaces.start(), offset);
- },
- [offset](const CompilerInsertion &) {
- if (offset) {
- *offset = 0;
- }
- return static_cast<const SourceFile *>(nullptr);
- },
- },
+ return common::visit(common::visitors{
+ [&](const Inclusion &inc) {
+ if (offset) {
+ *offset = origin.covers.MemberOffset(at);
+ }
+ return &inc.source;
+ },
+ [&](const Macro &) {
+ return GetSourceFile(
+ origin.replaces.start(), offset);
+ },
+ [offset](const CompilerInsertion &) {
+ if (offset) {
+ *offset = 0;
+ }
+ return static_cast<const SourceFile *>(nullptr);
+ },
+ },
origin.u);
}
@@ -325,7 +326,7 @@ const char *AllSources::GetSource(ProvenanceRange range) const {
std::optional<SourcePosition> AllSources::GetSourcePosition(
Provenance prov) const {
const Origin &origin{MapToOrigin(prov)};
- return std::visit(
+ return common::visit(
common::visitors{
[&](const Inclusion &inc) -> std::optional<SourcePosition> {
std::size_t offset{origin.covers.MemberOffset(prov)};
@@ -400,7 +401,7 @@ AllSources::Origin::Origin(ProvenanceRange r, const std::string &text)
: u{CompilerInsertion{text}}, covers{r} {}
const char &AllSources::Origin::operator[](std::size_t n) const {
- return std::visit(
+ return common::visit(
common::visitors{
[n](const Inclusion &inc) -> const char & {
return inc.source.content()[n];
@@ -511,23 +512,23 @@ llvm::raw_ostream &AllSources::Dump(llvm::raw_ostream &o) const {
o << " ";
DumpRange(o, m.covers);
o << " -> ";
- std::visit(common::visitors{
- [&](const Inclusion &inc) {
- if (inc.isModule) {
- o << "module ";
- }
- o << "file " << inc.source.path();
- },
- [&](const Macro &mac) { o << "macro " << mac.expansion; },
- [&](const CompilerInsertion &ins) {
- o << "compiler '" << ins.text << '\'';
- if (ins.text.length() == 1) {
- int ch = ins.text[0];
- o << "(0x";
- o.write_hex(ch & 0xff) << ")";
- }
- },
- },
+ common::visit(common::visitors{
+ [&](const Inclusion &inc) {
+ if (inc.isModule) {
+ o << "module ";
+ }
+ o << "file " << inc.source.path();
+ },
+ [&](const Macro &mac) { o << "macro " << mac.expansion; },
+ [&](const CompilerInsertion &ins) {
+ o << "compiler '" << ins.text << '\'';
+ if (ins.text.length() == 1) {
+ int ch = ins.text[0];
+ o << "(0x";
+ o.write_hex(ch & 0xff) << ")";
+ }
+ },
+ },
m.u);
if (IsValid(m.replaces)) {
o << " replaces ";
diff --git a/flang/lib/Parser/tools.cpp b/flang/lib/Parser/tools.cpp
index 2db832ab715fa..899fb0f069a93 100644
--- a/flang/lib/Parser/tools.cpp
+++ b/flang/lib/Parser/tools.cpp
@@ -17,7 +17,7 @@ const Name &GetLastName(const StructureComponent &x) {
}
const Name &GetLastName(const DataRef &x) {
- return std::visit(
+ return common::visit(
common::visitors{
[](const Name &name) -> const Name & { return name; },
[](const common::Indirection<StructureComponent> &sc)
@@ -36,7 +36,7 @@ const Name &GetLastName(const Substring &x) {
}
const Name &GetLastName(const Designator &x) {
- return std::visit(
+ return common::visit(
[](const auto &y) -> const Name & { return GetLastName(y); }, x.u);
}
@@ -45,7 +45,7 @@ const Name &GetLastName(const ProcComponentRef &x) {
}
const Name &GetLastName(const ProcedureDesignator &x) {
- return std::visit(
+ return common::visit(
[](const auto &y) -> const Name & { return GetLastName(y); }, x.u);
}
@@ -56,7 +56,7 @@ const Name &GetLastName(const Call &x) {
const Name &GetLastName(const FunctionReference &x) { return GetLastName(x.v); }
const Name &GetLastName(const Variable &x) {
- return std::visit(
+ return common::visit(
[](const auto &indirection) -> const Name & {
return GetLastName(indirection.value());
},
@@ -64,7 +64,7 @@ const Name &GetLastName(const Variable &x) {
}
const Name &GetLastName(const AllocateObject &x) {
- return std::visit(
+ return common::visit(
[](const auto &y) -> const Name & { return GetLastName(y); }, x.u);
}
@@ -75,7 +75,7 @@ const Name &GetFirstName(const StructureComponent &x) {
}
const Name &GetFirstName(const DataRef &x) {
- return std::visit(
+ return common::visit(
common::visitors{
[](const Name &name) -> const Name & { return name; },
[](const common::Indirection<StructureComponent> &sc)
@@ -94,7 +94,7 @@ const Name &GetFirstName(const Substring &x) {
}
const Name &GetFirstName(const Designator &x) {
- return std::visit(
+ return common::visit(
[](const auto &y) -> const Name & { return GetFirstName(y); }, x.u);
}
@@ -103,7 +103,7 @@ const Name &GetFirstName(const ProcComponentRef &x) {
}
const Name &GetFirstName(const ProcedureDesignator &x) {
- return std::visit(
+ return common::visit(
[](const auto &y) -> const Name & { return GetFirstName(y); }, x.u);
}
@@ -116,7 +116,7 @@ const Name &GetFirstName(const FunctionReference &x) {
}
const Name &GetFirstName(const Variable &x) {
- return std::visit(
+ return common::visit(
[](const auto &indirect) -> const Name & {
return GetFirstName(indirect.value());
},
@@ -124,7 +124,7 @@ const Name &GetFirstName(const Variable &x) {
}
const CoindexedNamedObject *GetCoindexedNamedObject(const DataRef &base) {
- return std::visit(
+ return common::visit(
common::visitors{
[](const Name &) -> const CoindexedNamedObject * { return nullptr; },
[](const common::Indirection<CoindexedNamedObject> &x)
@@ -137,19 +137,19 @@ const CoindexedNamedObject *GetCoindexedNamedObject(const DataRef &base) {
}
const CoindexedNamedObject *GetCoindexedNamedObject(
const Designator &designator) {
- return std::visit(common::visitors{
- [](const DataRef &x) -> const CoindexedNamedObject * {
- return GetCoindexedNamedObject(x);
- },
- [](const Substring &x) -> const CoindexedNamedObject * {
- return GetCoindexedNamedObject(
- std::get<DataRef>(x.t));
- },
- },
+ return common::visit(
+ common::visitors{
+ [](const DataRef &x) -> const CoindexedNamedObject * {
+ return GetCoindexedNamedObject(x);
+ },
+ [](const Substring &x) -> const CoindexedNamedObject * {
+ return GetCoindexedNamedObject(std::get<DataRef>(x.t));
+ },
+ },
designator.u);
}
const CoindexedNamedObject *GetCoindexedNamedObject(const Variable &variable) {
- return std::visit(
+ return common::visit(
common::visitors{
[](const common::Indirection<Designator> &designator)
-> const CoindexedNamedObject * {
@@ -161,7 +161,7 @@ const CoindexedNamedObject *GetCoindexedNamedObject(const Variable &variable) {
}
const CoindexedNamedObject *GetCoindexedNamedObject(
const AllocateObject &allocateObject) {
- return std::visit(
+ return common::visit(
common::visitors{
[](const StructureComponent &x) -> const CoindexedNamedObject * {
return GetCoindexedNamedObject(x.base);
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index f6b4ad2f19c6b..c52ad06eeacec 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -165,7 +165,7 @@ class UnparseVisitor {
Word("INTEGER");
}
void Unparse(const KindSelector &x) { // R706
- std::visit(
+ common::visit(
common::visitors{
[&](const ScalarIntConstantExpr &y) {
Put('('), Word("KIND="), Walk(y), Put(')');
@@ -196,16 +196,16 @@ class UnparseVisitor {
Walk(", LEN=", x.length), Put(')');
}
void Unparse(const LengthSelector &x) { // R722
- std::visit(common::visitors{
- [&](const TypeParamValue &y) {
- Put('('), Word("LEN="), Walk(y), Put(')');
- },
- [&](const CharLength &y) { Put('*'), Walk(y); },
- },
+ common::visit(common::visitors{
+ [&](const TypeParamValue &y) {
+ Put('('), Word("LEN="), Walk(y), Put(')');
+ },
+ [&](const CharLength &y) { Put('*'), Walk(y); },
+ },
x.u);
}
void Unparse(const CharLength &x) { // R723
- std::visit(
+ common::visit(
common::visitors{
[&](const TypeParamValue &y) { Put('('), Walk(y), Put(')'); },
[&](const std::int64_t &y) { Walk(y); },
@@ -271,7 +271,7 @@ class UnparseVisitor {
(!std::holds_alternative<DeclarationTypeSpec::Record>(dts.u) &&
std::none_of(
decls.begin(), decls.end(), [](const ComponentOrFill &c) {
- return std::visit(
+ return common::visit(
common::visitors{
[](const ComponentDecl &d) {
const auto &init{
@@ -295,19 +295,19 @@ class UnparseVisitor {
void Unparse(const Pointer &) { Word("POINTER"); }
void Unparse(const Contiguous &) { Word("CONTIGUOUS"); }
void Before(const ComponentAttrSpec &x) {
- std::visit(common::visitors{
- [&](const CoarraySpec &) { Word("CODIMENSION["); },
- [&](const ComponentArraySpec &) { Word("DIMENSION("); },
- [](const auto &) {},
- },
+ common::visit(common::visitors{
+ [&](const CoarraySpec &) { Word("CODIMENSION["); },
+ [&](const ComponentArraySpec &) { Word("DIMENSION("); },
+ [](const auto &) {},
+ },
x.u);
}
void Post(const ComponentAttrSpec &x) {
- std::visit(common::visitors{
- [&](const CoarraySpec &) { Put(']'); },
- [&](const ComponentArraySpec &) { Put(')'); },
- [](const auto &) {},
- },
+ common::visit(common::visitors{
+ [&](const CoarraySpec &) { Put(']'); },
+ [&](const ComponentArraySpec &) { Put(')'); },
+ [](const auto &) {},
+ },
x.u);
}
void Unparse(const ComponentDecl &x) { // R739
@@ -323,10 +323,11 @@ class UnparseVisitor {
Walk("*", std::get<std::optional<CharLength>>(x.t));
}
void Unparse(const ComponentArraySpec &x) { // R740
- std::visit(common::visitors{
- [&](const std::list<ExplicitShapeSpec> &y) { Walk(y, ","); },
- [&](const DeferredShapeSpecList &y) { Walk(y); },
- },
+ common::visit(
+ common::visitors{
+ [&](const std::list<ExplicitShapeSpec> &y) { Walk(y, ","); },
+ [&](const DeferredShapeSpecList &y) { Walk(y); },
+ },
x.u);
}
void Unparse(const ProcComponentDefStmt &x) { // R741
@@ -340,14 +341,15 @@ class UnparseVisitor {
}
void Unparse(const Pass &x) { Word("PASS"), Walk("(", x.v, ")"); }
void Unparse(const Initialization &x) { // R743 & R805
- std::visit(common::visitors{
- [&](const ConstantExpr &y) { Put(" = "), Walk(y); },
- [&](const NullInit &y) { Put(" => "), Walk(y); },
- [&](const InitialDataTarget &y) { Put(" => "), Walk(y); },
- [&](const std::list<common::Indirection<DataStmtValue>> &y) {
- Walk("/", y, ", ", "/");
- },
- },
+ common::visit(
+ common::visitors{
+ [&](const ConstantExpr &y) { Put(" = "), Walk(y); },
+ [&](const NullInit &y) { Put(" => "), Walk(y); },
+ [&](const InitialDataTarget &y) { Put(" => "), Walk(y); },
+ [&](const std::list<common::Indirection<DataStmtValue>> &y) {
+ Walk("/", y, ", ", "/");
+ },
+ },
x.u);
}
void Unparse(const PrivateStmt &) { // R745
@@ -487,19 +489,19 @@ class UnparseVisitor {
Put(' '), Walk(std::get<std::list<EntityDecl>>(x.t), ", ");
}
void Before(const AttrSpec &x) { // R802
- std::visit(common::visitors{
- [&](const CoarraySpec &) { Word("CODIMENSION["); },
- [&](const ArraySpec &) { Word("DIMENSION("); },
- [](const auto &) {},
- },
+ common::visit(common::visitors{
+ [&](const CoarraySpec &) { Word("CODIMENSION["); },
+ [&](const ArraySpec &) { Word("DIMENSION("); },
+ [](const auto &) {},
+ },
x.u);
}
void Post(const AttrSpec &x) {
- std::visit(common::visitors{
- [&](const CoarraySpec &) { Put(']'); },
- [&](const ArraySpec &) { Put(')'); },
- [](const auto &) {},
- },
+ common::visit(common::visitors{
+ [&](const CoarraySpec &) { Put(']'); },
+ [&](const ArraySpec &) { Put(')'); },
+ [](const auto &) {},
+ },
x.u);
}
void Unparse(const EntityDecl &x) { // R803
@@ -516,10 +518,10 @@ class UnparseVisitor {
Word("BIND(C"), Walk(", NAME=", x.v), Put(')');
}
void Unparse(const CoarraySpec &x) { // R809
- std::visit(common::visitors{
- [&](const DeferredCoshapeSpecList &y) { Walk(y); },
- [&](const ExplicitCoshapeSpec &y) { Walk(y); },
- },
+ common::visit(common::visitors{
+ [&](const DeferredCoshapeSpecList &y) { Walk(y); },
+ [&](const ExplicitCoshapeSpec &y) { Walk(y); },
+ },
x.u);
}
void Unparse(const DeferredCoshapeSpecList &x) { // R810
@@ -539,14 +541,15 @@ class UnparseVisitor {
Walk(std::get<SpecificationExpr>(x.t));
}
void Unparse(const ArraySpec &x) { // R815
- std::visit(common::visitors{
- [&](const std::list<ExplicitShapeSpec> &y) { Walk(y, ","); },
- [&](const std::list<AssumedShapeSpec> &y) { Walk(y, ","); },
- [&](const DeferredShapeSpecList &y) { Walk(y); },
- [&](const AssumedSizeSpec &y) { Walk(y); },
- [&](const ImpliedShapeSpec &y) { Walk(y); },
- [&](const AssumedRankSpec &y) { Walk(y); },
- },
+ common::visit(
+ common::visitors{
+ [&](const std::list<ExplicitShapeSpec> &y) { Walk(y, ","); },
+ [&](const std::list<AssumedShapeSpec> &y) { Walk(y, ","); },
+ [&](const DeferredShapeSpecList &y) { Walk(y); },
+ [&](const AssumedSizeSpec &y) { Walk(y); },
+ [&](const ImpliedShapeSpec &y) { Walk(y); },
+ [&](const AssumedRankSpec &y) { Walk(y); },
+ },
x.u);
}
void Post(const AssumedShapeSpec &) { Put(':'); } // R819
@@ -681,12 +684,13 @@ class UnparseVisitor {
}
void Unparse(const ImplicitStmt &x) { // R863
Word("IMPLICIT ");
- std::visit(common::visitors{
- [&](const std::list<ImplicitSpec> &y) { Walk(y, ", "); },
- [&](const std::list<ImplicitStmt::ImplicitNoneNameSpec> &y) {
- Word("NONE"), Walk(" (", y, ", ", ")");
- },
- },
+ common::visit(
+ common::visitors{
+ [&](const std::list<ImplicitSpec> &y) { Walk(y, ", "); },
+ [&](const std::list<ImplicitStmt::ImplicitNoneNameSpec> &y) {
+ Word("NONE"), Walk(" (", y, ", ", ")");
+ },
+ },
x.u);
}
void Unparse(const ImplicitSpec &x) { // R864
@@ -800,11 +804,11 @@ class UnparseVisitor {
Walk(", ", std::get<std::list<AllocOpt>>(x.t), ", "), Put(')');
}
void Before(const AllocOpt &x) { // R928, R931
- std::visit(common::visitors{
- [&](const AllocOpt::Mold &) { Word("MOLD="); },
- [&](const AllocOpt::Source &) { Word("SOURCE="); },
- [](const StatOrErrmsg &) {},
- },
+ common::visit(common::visitors{
+ [&](const AllocOpt::Mold &) { Word("MOLD="); },
+ [&](const AllocOpt::Source &) { Word("SOURCE="); },
+ [](const StatOrErrmsg &) {},
+ },
x.u);
}
void Unparse(const Allocation &x) { // R932
@@ -829,10 +833,10 @@ class UnparseVisitor {
Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
}
void Before(const StatOrErrmsg &x) { // R942 & R1165
- std::visit(common::visitors{
- [&](const StatVariable &) { Word("STAT="); },
- [&](const MsgVariable &) { Word("ERRMSG="); },
- },
+ common::visit(common::visitors{
+ [&](const StatVariable &) { Word("STAT="); },
+ [&](const MsgVariable &) { Word("ERRMSG="); },
+ },
x.u);
}
@@ -887,7 +891,7 @@ class UnparseVisitor {
Put('\n');
} else {
Walk(std::get<DataRef>(x.t));
- std::visit(
+ common::visit(
common::visitors{
[&](const std::list<BoundsRemapping> &y) {
Put('('), Walk(y), Put(')');
@@ -991,12 +995,12 @@ class UnparseVisitor {
Word("DO "), Walk(std::get<std::optional<LoopControl>>(x.t));
}
void Unparse(const LoopControl &x) { // R1123
- std::visit(common::visitors{
- [&](const ScalarLogicalExpr &y) {
- Word("WHILE ("), Walk(y), Put(')');
- },
- [&](const auto &y) { Walk(y); },
- },
+ common::visit(common::visitors{
+ [&](const ScalarLogicalExpr &y) {
+ Word("WHILE ("), Walk(y), Put(')');
+ },
+ [&](const auto &y) { Walk(y); },
+ },
x.u);
}
void Unparse(const ConcurrentHeader &x) { // R1125
@@ -1060,12 +1064,12 @@ class UnparseVisitor {
Outdent(), Word("END SELECT"), Walk(" ", x.v);
}
void Unparse(const CaseSelector &x) { // R1145
- std::visit(common::visitors{
- [&](const std::list<CaseValueRange> &y) {
- Put('('), Walk(y), Put(')');
- },
- [&](const Default &) { Word("DEFAULT"); },
- },
+ common::visit(common::visitors{
+ [&](const std::list<CaseValueRange> &y) {
+ Put('('), Walk(y), Put(')');
+ },
+ [&](const Default &) { Word("DEFAULT"); },
+ },
x.u);
}
void Unparse(const CaseValueRange::Range &x) { // R1146
@@ -1078,13 +1082,13 @@ class UnparseVisitor {
}
void Unparse(const SelectRankCaseStmt &x) { // R1150
Outdent(), Word("RANK ");
- std::visit(common::visitors{
- [&](const ScalarIntConstantExpr &y) {
- Put('('), Walk(y), Put(')');
- },
- [&](const Star &) { Put("(*)"); },
- [&](const Default &) { Word("DEFAULT"); },
- },
+ common::visit(common::visitors{
+ [&](const ScalarIntConstantExpr &y) {
+ Put('('), Walk(y), Put(')');
+ },
+ [&](const Star &) { Put("(*)"); },
+ [&](const Default &) { Word("DEFAULT"); },
+ },
std::get<SelectRankCaseStmt::Rank>(x.t).u);
Walk(" ", std::get<std::optional<Name>>(x.t)), Indent();
}
@@ -1098,7 +1102,7 @@ class UnparseVisitor {
Walk(" ", std::get<std::optional<Name>>(x.t)), Indent();
}
void Unparse(const TypeGuardStmt::Guard &x) {
- std::visit(
+ common::visit(
common::visitors{
[&](const TypeSpec &y) { Word("TYPE IS ("), Walk(y), Put(')'); },
[&](const DerivedTypeSpec &y) {
@@ -1150,10 +1154,10 @@ class UnparseVisitor {
Walk(", ", std::get<std::list<StatOrErrmsg>>(x.t), ", "), Put(')');
}
void Before(const EventWaitStmt::EventWaitSpec &x) { // R1173, R1174
- std::visit(common::visitors{
- [&](const ScalarIntExpr &) { Word("UNTIL_COUNT="); },
- [](const StatOrErrmsg &) {},
- },
+ common::visit(common::visitors{
+ [&](const ScalarIntExpr &) { Word("UNTIL_COUNT="); },
+ [](const StatOrErrmsg &) {},
+ },
x.u);
}
void Unparse(const EventWaitStmt &x) { // R1170
@@ -1168,10 +1172,10 @@ class UnparseVisitor {
Put(')');
}
void Before(const FormTeamStmt::FormTeamSpec &x) { // R1176, R1178
- std::visit(common::visitors{
- [&](const ScalarIntExpr &) { Word("NEW_INDEX="); },
- [](const StatOrErrmsg &) {},
- },
+ common::visit(common::visitors{
+ [&](const ScalarIntExpr &) { Word("NEW_INDEX="); },
+ [](const StatOrErrmsg &) {},
+ },
x.u);
}
void Unparse(const LockStmt &x) { // R1179
@@ -1180,7 +1184,7 @@ class UnparseVisitor {
Put(')');
}
void Before(const LockStmt::LockStat &x) { // R1180
- std::visit(
+ common::visit(
common::visitors{
[&](const ScalarLogicalVariable &) { Word("ACQUIRED_LOCK="); },
[](const StatOrErrmsg &) {},
@@ -1197,57 +1201,57 @@ class UnparseVisitor {
Word("OPEN ("), Walk(x.v, ", "), Put(')');
}
bool Pre(const ConnectSpec &x) { // R1205
- return std::visit(common::visitors{
- [&](const FileUnitNumber &) {
- Word("UNIT=");
- return true;
- },
- [&](const FileNameExpr &) {
- Word("FILE=");
- return true;
- },
- [&](const ConnectSpec::CharExpr &y) {
- Walk(y.t, "=");
- return false;
- },
- [&](const MsgVariable &) {
- Word("IOMSG=");
- return true;
- },
- [&](const StatVariable &) {
- Word("IOSTAT=");
- return true;
- },
- [&](const ConnectSpec::Recl &) {
- Word("RECL=");
- return true;
- },
- [&](const ConnectSpec::Newunit &) {
- Word("NEWUNIT=");
- return true;
- },
- [&](const ErrLabel &) {
- Word("ERR=");
- return true;
- },
- [&](const StatusExpr &) {
- Word("STATUS=");
- return true;
- },
- },
+ return common::visit(common::visitors{
+ [&](const FileUnitNumber &) {
+ Word("UNIT=");
+ return true;
+ },
+ [&](const FileNameExpr &) {
+ Word("FILE=");
+ return true;
+ },
+ [&](const ConnectSpec::CharExpr &y) {
+ Walk(y.t, "=");
+ return false;
+ },
+ [&](const MsgVariable &) {
+ Word("IOMSG=");
+ return true;
+ },
+ [&](const StatVariable &) {
+ Word("IOSTAT=");
+ return true;
+ },
+ [&](const ConnectSpec::Recl &) {
+ Word("RECL=");
+ return true;
+ },
+ [&](const ConnectSpec::Newunit &) {
+ Word("NEWUNIT=");
+ return true;
+ },
+ [&](const ErrLabel &) {
+ Word("ERR=");
+ return true;
+ },
+ [&](const StatusExpr &) {
+ Word("STATUS=");
+ return true;
+ },
+ },
x.u);
}
void Unparse(const CloseStmt &x) { // R1208
Word("CLOSE ("), Walk(x.v, ", "), Put(')');
}
void Before(const CloseStmt::CloseSpec &x) { // R1209
- std::visit(common::visitors{
- [&](const FileUnitNumber &) { Word("UNIT="); },
- [&](const StatVariable &) { Word("IOSTAT="); },
- [&](const MsgVariable &) { Word("IOMSG="); },
- [&](const ErrLabel &) { Word("ERR="); },
- [&](const StatusExpr &) { Word("STATUS="); },
- },
+ common::visit(common::visitors{
+ [&](const FileUnitNumber &) { Word("UNIT="); },
+ [&](const StatVariable &) { Word("IOSTAT="); },
+ [&](const MsgVariable &) { Word("IOMSG="); },
+ [&](const ErrLabel &) { Word("ERR="); },
+ [&](const StatusExpr &) { Word("STATUS="); },
+ },
x.u);
}
void Unparse(const ReadStmt &x) { // R1210
@@ -1287,64 +1291,64 @@ class UnparseVisitor {
Walk(", ", std::get<std::list<OutputItem>>(x.t), ", ");
}
bool Pre(const IoControlSpec &x) { // R1213
- return std::visit(common::visitors{
- [&](const IoUnit &) {
- Word("UNIT=");
- return true;
- },
- [&](const Format &) {
- Word("FMT=");
- return true;
- },
- [&](const Name &) {
- Word("NML=");
- return true;
- },
- [&](const IoControlSpec::CharExpr &y) {
- Walk(y.t, "=");
- return false;
- },
- [&](const IoControlSpec::Asynchronous &) {
- Word("ASYNCHRONOUS=");
- return true;
- },
- [&](const EndLabel &) {
- Word("END=");
- return true;
- },
- [&](const EorLabel &) {
- Word("EOR=");
- return true;
- },
- [&](const ErrLabel &) {
- Word("ERR=");
- return true;
- },
- [&](const IdVariable &) {
- Word("ID=");
- return true;
- },
- [&](const MsgVariable &) {
- Word("IOMSG=");
- return true;
- },
- [&](const StatVariable &) {
- Word("IOSTAT=");
- return true;
- },
- [&](const IoControlSpec::Pos &) {
- Word("POS=");
- return true;
- },
- [&](const IoControlSpec::Rec &) {
- Word("REC=");
- return true;
- },
- [&](const IoControlSpec::Size &) {
- Word("SIZE=");
- return true;
- },
- },
+ return common::visit(common::visitors{
+ [&](const IoUnit &) {
+ Word("UNIT=");
+ return true;
+ },
+ [&](const Format &) {
+ Word("FMT=");
+ return true;
+ },
+ [&](const Name &) {
+ Word("NML=");
+ return true;
+ },
+ [&](const IoControlSpec::CharExpr &y) {
+ Walk(y.t, "=");
+ return false;
+ },
+ [&](const IoControlSpec::Asynchronous &) {
+ Word("ASYNCHRONOUS=");
+ return true;
+ },
+ [&](const EndLabel &) {
+ Word("END=");
+ return true;
+ },
+ [&](const EorLabel &) {
+ Word("EOR=");
+ return true;
+ },
+ [&](const ErrLabel &) {
+ Word("ERR=");
+ return true;
+ },
+ [&](const IdVariable &) {
+ Word("ID=");
+ return true;
+ },
+ [&](const MsgVariable &) {
+ Word("IOMSG=");
+ return true;
+ },
+ [&](const StatVariable &) {
+ Word("IOSTAT=");
+ return true;
+ },
+ [&](const IoControlSpec::Pos &) {
+ Word("POS=");
+ return true;
+ },
+ [&](const IoControlSpec::Rec &) {
+ Word("REC=");
+ return true;
+ },
+ [&](const IoControlSpec::Size &) {
+ Word("SIZE=");
+ return true;
+ },
+ },
x.u);
}
void Unparse(const InputImpliedDo &x) { // R1218
@@ -1359,15 +1363,15 @@ class UnparseVisitor {
Word("WAIT ("), Walk(x.v, ", "), Put(')');
}
void Before(const WaitSpec &x) { // R1223
- std::visit(common::visitors{
- [&](const FileUnitNumber &) { Word("UNIT="); },
- [&](const EndLabel &) { Word("END="); },
- [&](const EorLabel &) { Word("EOR="); },
- [&](const ErrLabel &) { Word("ERR="); },
- [&](const IdExpr &) { Word("ID="); },
- [&](const MsgVariable &) { Word("IOMSG="); },
- [&](const StatVariable &) { Word("IOSTAT="); },
- },
+ common::visit(common::visitors{
+ [&](const FileUnitNumber &) { Word("UNIT="); },
+ [&](const EndLabel &) { Word("END="); },
+ [&](const EorLabel &) { Word("EOR="); },
+ [&](const ErrLabel &) { Word("ERR="); },
+ [&](const IdExpr &) { Word("ID="); },
+ [&](const MsgVariable &) { Word("IOMSG="); },
+ [&](const StatVariable &) { Word("IOSTAT="); },
+ },
x.u);
}
void Unparse(const BackspaceStmt &x) { // R1224
@@ -1380,12 +1384,12 @@ class UnparseVisitor {
Word("REWIND ("), Walk(x.v, ", "), Put(')');
}
void Before(const PositionOrFlushSpec &x) { // R1227 & R1229
- std::visit(common::visitors{
- [&](const FileUnitNumber &) { Word("UNIT="); },
- [&](const MsgVariable &) { Word("IOMSG="); },
- [&](const StatVariable &) { Word("IOSTAT="); },
- [&](const ErrLabel &) { Word("ERR="); },
- },
+ common::visit(common::visitors{
+ [&](const FileUnitNumber &) { Word("UNIT="); },
+ [&](const MsgVariable &) { Word("IOMSG="); },
+ [&](const StatVariable &) { Word("IOSTAT="); },
+ [&](const ErrLabel &) { Word("ERR="); },
+ },
x.u);
}
void Unparse(const FlushStmt &x) { // R1228
@@ -1393,7 +1397,7 @@ class UnparseVisitor {
}
void Unparse(const InquireStmt &x) { // R1230
Word("INQUIRE (");
- std::visit(
+ common::visit(
common::visitors{
[&](const InquireStmt::Iolength &y) {
Word("IOLENGTH="), Walk(y.t, ") ");
@@ -1403,36 +1407,36 @@ class UnparseVisitor {
x.u);
}
bool Pre(const InquireSpec &x) { // R1231
- return std::visit(common::visitors{
- [&](const FileUnitNumber &) {
- Word("UNIT=");
- return true;
- },
- [&](const FileNameExpr &) {
- Word("FILE=");
- return true;
- },
- [&](const InquireSpec::CharVar &y) {
- Walk(y.t, "=");
- return false;
- },
- [&](const InquireSpec::IntVar &y) {
- Walk(y.t, "=");
- return false;
- },
- [&](const InquireSpec::LogVar &y) {
- Walk(y.t, "=");
- return false;
- },
- [&](const IdExpr &) {
- Word("ID=");
- return true;
- },
- [&](const ErrLabel &) {
- Word("ERR=");
- return true;
- },
- },
+ return common::visit(common::visitors{
+ [&](const FileUnitNumber &) {
+ Word("UNIT=");
+ return true;
+ },
+ [&](const FileNameExpr &) {
+ Word("FILE=");
+ return true;
+ },
+ [&](const InquireSpec::CharVar &y) {
+ Walk(y.t, "=");
+ return false;
+ },
+ [&](const InquireSpec::IntVar &y) {
+ Walk(y.t, "=");
+ return false;
+ },
+ [&](const InquireSpec::LogVar &y) {
+ Walk(y.t, "=");
+ return false;
+ },
+ [&](const IdExpr &) {
+ Word("ID=");
+ return true;
+ },
+ [&](const ErrLabel &) {
+ Word("ERR=");
+ return true;
+ },
+ },
x.u);
}
@@ -1447,13 +1451,13 @@ class UnparseVisitor {
if (x.repeatCount) {
Walk(*x.repeatCount);
}
- std::visit(common::visitors{
- [&](const std::string &y) { PutNormalized(y); },
- [&](const std::list<format::FormatItem> &y) {
- Walk("(", y, ",", ")");
- },
- [&](const auto &y) { Walk(y); },
- },
+ common::visit(common::visitors{
+ [&](const std::string &y) { PutNormalized(y); },
+ [&](const std::list<format::FormatItem> &y) {
+ Walk("(", y, ",", ")");
+ },
+ [&](const auto &y) { Walk(y); },
+ },
x.u);
}
void Unparse(
@@ -1566,19 +1570,21 @@ class UnparseVisitor {
}
void Unparse(const UseStmt &x) { // R1409
Word("USE"), Walk(", ", x.nature), Put(" :: "), Walk(x.moduleName);
- std::visit(common::visitors{
- [&](const std::list<Rename> &y) { Walk(", ", y, ", "); },
- [&](const std::list<Only> &y) { Walk(", ONLY: ", y, ", "); },
- },
+ common::visit(
+ common::visitors{
+ [&](const std::list<Rename> &y) { Walk(", ", y, ", "); },
+ [&](const std::list<Only> &y) { Walk(", ONLY: ", y, ", "); },
+ },
x.u);
}
void Unparse(const Rename &x) { // R1411
- std::visit(common::visitors{
- [&](const Rename::Names &y) { Walk(y.t, " => "); },
- [&](const Rename::Operators &y) {
- Word("OPERATOR("), Walk(y.t, ") => OPERATOR("), Put(")");
- },
- },
+ common::visit(common::visitors{
+ [&](const Rename::Names &y) { Walk(y.t, " => "); },
+ [&](const Rename::Operators &y) {
+ Word("OPERATOR("), Walk(y.t, ") => OPERATOR("),
+ Put(")");
+ },
+ },
x.u);
}
void Unparse(const SubmoduleStmt &x) { // R1417
@@ -1598,12 +1604,12 @@ class UnparseVisitor {
}
void Unparse(const InterfaceStmt &x) { // R1503
- std::visit(common::visitors{
- [&](const std::optional<GenericSpec> &y) {
- Word("INTERFACE"), Walk(" ", y);
- },
- [&](const Abstract &) { Word("ABSTRACT INTERFACE"); },
- },
+ common::visit(common::visitors{
+ [&](const std::optional<GenericSpec> &y) {
+ Word("INTERFACE"), Walk(" ", y);
+ },
+ [&](const Abstract &) { Word("ABSTRACT INTERFACE"); },
+ },
x.u);
Indent();
}
@@ -1619,7 +1625,7 @@ class UnparseVisitor {
Walk(std::get<std::list<Name>>(x.t), ", ");
}
void Before(const GenericSpec &x) { // R1508, R1509
- std::visit(
+ common::visit(
common::visitors{
[&](const DefinedOperator &) { Word("OPERATOR("); },
[&](const GenericSpec::Assignment &) { Word("ASSIGNMENT(=)"); },
@@ -1640,10 +1646,10 @@ class UnparseVisitor {
x.u);
}
void Post(const GenericSpec &x) {
- std::visit(common::visitors{
- [&](const DefinedOperator &) { Put(')'); },
- [](const auto &) {},
- },
+ common::visit(common::visitors{
+ [&](const DefinedOperator &) { Put(')'); },
+ [](const auto &) {},
+ },
x.u);
}
void Unparse(const GenericStmt &x) { // R1510
@@ -1767,7 +1773,7 @@ class UnparseVisitor {
// Directives, extensions, and deprecated constructs
void Unparse(const CompilerDirective &x) {
- std::visit(
+ common::visit(
common::visitors{
[&](const std::list<CompilerDirective::IgnoreTKR> &tkr) {
Word("!DIR$ IGNORE_TKR"); // emitted even if tkr list is empty
@@ -1852,12 +1858,12 @@ class UnparseVisitor {
Word(AccDataModifier::EnumToString(x));
}
void Unparse(const AccBindClause &x) {
- std::visit(common::visitors{
- [&](const Name &y) { Put('('), Walk(y), Put(')'); },
- [&](const ScalarDefaultCharExpr &y) {
- Put('('), Walk(y), Put(')');
- },
- },
+ common::visit(common::visitors{
+ [&](const Name &y) { Put('('), Walk(y), Put(')'); },
+ [&](const ScalarDefaultCharExpr &y) {
+ Put('('), Walk(y), Put(')');
+ },
+ },
x.u);
}
void Unparse(const AccDefaultClause &x) {
@@ -1937,10 +1943,10 @@ class UnparseVisitor {
EndOpenACC();
}
void Unparse(const AccObject &x) {
- std::visit(common::visitors{
- [&](const Designator &y) { Walk(y); },
- [&](const Name &y) { Put("/"), Walk(y), Put("/"); },
- },
+ common::visit(common::visitors{
+ [&](const Designator &y) { Walk(y); },
+ [&](const Name &y) { Put("/"), Walk(y), Put("/"); },
+ },
x.u);
}
void Unparse(const AccObjectList &x) { Walk(x.v, ","); }
@@ -1978,10 +1984,10 @@ class UnparseVisitor {
// OpenMP Clauses & Directives
void Unparse(const OmpObject &x) {
- std::visit(common::visitors{
- [&](const Designator &y) { Walk(y); },
- [&](const Name &y) { Put("/"), Walk(y), Put("/"); },
- },
+ common::visit(common::visitors{
+ [&](const Designator &y) { Walk(y); },
+ [&](const Name &y) { Put("/"), Walk(y), Put("/"); },
+ },
x.u);
}
void Unparse(const OmpMapType::Always &) { Word("ALWAYS,"); }
@@ -2040,19 +2046,20 @@ class UnparseVisitor {
Put(")");
}
bool Pre(const OmpDependClause &x) {
- return std::visit(common::visitors{
- [&](const OmpDependClause::Source &) {
- Word("SOURCE");
- return false;
- },
- [&](const OmpDependClause::Sink &y) {
- Word("SINK:");
- Walk(y.v);
- Put(")");
- return false;
- },
- [&](const OmpDependClause::InOut &) { return true; },
- },
+ return common::visit(
+ common::visitors{
+ [&](const OmpDependClause::Source &) {
+ Word("SOURCE");
+ return false;
+ },
+ [&](const OmpDependClause::Sink &y) {
+ Word("SINK:");
+ Walk(y.v);
+ Put(")");
+ return false;
+ },
+ [&](const OmpDependClause::InOut &) { return true; },
+ },
x.u);
}
void Unparse(const OmpDefaultmapClause &x) {
@@ -2346,37 +2353,38 @@ class UnparseVisitor {
bool Pre(const OpenMPDeclarativeConstruct &x) {
BeginOpenMP();
Word("!$OMP ");
- return std::visit(common::visitors{
- [&](const OpenMPDeclarativeAllocate &z) {
- Word("ALLOCATE (");
- Walk(std::get<OmpObjectList>(z.t));
- Put(")");
- Walk(std::get<OmpClauseList>(z.t));
- Put("\n");
- EndOpenMP();
- return false;
- },
- [&](const OpenMPDeclareReductionConstruct &) {
- Word("DECLARE REDUCTION ");
- return true;
- },
- [&](const OpenMPDeclareSimdConstruct &y) {
- Word("DECLARE SIMD ");
- Walk("(", std::get<std::optional<Name>>(y.t), ")");
- Walk(std::get<OmpClauseList>(y.t));
- Put("\n");
- EndOpenMP();
- return false;
- },
- [&](const OpenMPDeclareTargetConstruct &) {
- Word("DECLARE TARGET ");
- return true;
- },
- [&](const OpenMPThreadprivate &) {
- Word("THREADPRIVATE (");
- return true;
- },
- },
+ return common::visit(
+ common::visitors{
+ [&](const OpenMPDeclarativeAllocate &z) {
+ Word("ALLOCATE (");
+ Walk(std::get<OmpObjectList>(z.t));
+ Put(")");
+ Walk(std::get<OmpClauseList>(z.t));
+ Put("\n");
+ EndOpenMP();
+ return false;
+ },
+ [&](const OpenMPDeclareReductionConstruct &) {
+ Word("DECLARE REDUCTION ");
+ return true;
+ },
+ [&](const OpenMPDeclareSimdConstruct &y) {
+ Word("DECLARE SIMD ");
+ Walk("(", std::get<std::optional<Name>>(y.t), ")");
+ Walk(std::get<OmpClauseList>(y.t));
+ Put("\n");
+ EndOpenMP();
+ return false;
+ },
+ [&](const OpenMPDeclareTargetConstruct &) {
+ Word("DECLARE TARGET ");
+ return true;
+ },
+ [&](const OpenMPThreadprivate &) {
+ Word("THREADPRIVATE (");
+ return true;
+ },
+ },
x.u);
}
void Post(const OpenMPDeclarativeConstruct &) {
@@ -2440,10 +2448,10 @@ class UnparseVisitor {
}
void Unparse(const OmpMemoryOrderClause &x) { Walk(x.v); }
void Unparse(const OmpAtomicClause &x) {
- std::visit(common::visitors{
- [&](const OmpMemoryOrderClause &y) { Walk(y); },
- [&](const OmpClause &z) { Walk(z); },
- },
+ common::visit(common::visitors{
+ [&](const OmpMemoryOrderClause &y) { Walk(y); },
+ [&](const OmpClause &z) { Walk(z); },
+ },
x.u);
}
void Unparse(const OpenMPFlushConstruct &x) {
diff --git a/flang/lib/Semantics/canonicalize-do.cpp b/flang/lib/Semantics/canonicalize-do.cpp
index 797fb27b2b14c..6aab4b7bc49dd 100644
--- a/flang/lib/Semantics/canonicalize-do.cpp
+++ b/flang/lib/Semantics/canonicalize-do.cpp
@@ -24,7 +24,7 @@ class CanonicalizationOfDoLoops {
std::vector<LabelInfo> stack;
for (auto i{block.begin()}, end{block.end()}; i != end; ++i) {
if (auto *executableConstruct{std::get_if<ExecutableConstruct>(&i->u)}) {
- std::visit(
+ common::visit(
common::visitors{
[](auto &) {},
// Labels on end-stmt of constructs are accepted by f18 as an
diff --git a/flang/lib/Semantics/check-allocate.cpp b/flang/lib/Semantics/check-allocate.cpp
index 63a1132630bb7..ce81ca1a2a076 100644
--- a/flang/lib/Semantics/check-allocate.cpp
+++ b/flang/lib/Semantics/check-allocate.cpp
@@ -128,10 +128,10 @@ static std::optional<AllocateCheckerInfo> CheckAllocateOptions(
const parser::Expr *parserSourceExpr{nullptr};
for (const parser::AllocOpt &allocOpt :
std::get<std::list<parser::AllocOpt>>(allocateStmt.t)) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::StatOrErrmsg &statOrErr) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::StatVariable &) {
if (info.gotStat) { // C943
diff --git a/flang/lib/Semantics/check-call.cpp b/flang/lib/Semantics/check-call.cpp
index 3410bf541b122..301f905b58bd2 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -672,7 +672,7 @@ static void CheckExplicitInterfaceArg(evaluate::ActualArgument &arg,
}
auto restorer{
messages.SetLocation(arg.sourceLocation().value_or(messages.at()))};
- std::visit(
+ common::visit(
common::visitors{
[&](const characteristics::DummyDataObject &object) {
ConvertBOZLiteralArg(arg, object.type.type());
diff --git a/flang/lib/Semantics/check-case.cpp b/flang/lib/Semantics/check-case.cpp
index bd1bb073539d2..4e37f4e1c5e3c 100644
--- a/flang/lib/Semantics/check-case.cpp
+++ b/flang/lib/Semantics/check-case.cpp
@@ -43,7 +43,7 @@ template <typename T> class CaseValues {
const auto &stmt{std::get<parser::Statement<parser::CaseStmt>>(c.t)};
const parser::CaseStmt &caseStmt{stmt.statement};
const auto &selector{std::get<parser::CaseSelector>(caseStmt.t)};
- std::visit(
+ common::visit(
common::visitors{
[&](const std::list<parser::CaseValueRange> &ranges) {
for (const auto &range : ranges) {
@@ -117,25 +117,26 @@ template <typename T> class CaseValues {
using PairOfValues = std::pair<std::optional<Value>, std::optional<Value>>;
PairOfValues ComputeBounds(const parser::CaseValueRange &range) {
- return std::visit(common::visitors{
- [&](const parser::CaseValue &x) {
- auto value{GetValue(x)};
- return PairOfValues{value, value};
- },
- [&](const parser::CaseValueRange::Range &x) {
- std::optional<Value> lo, hi;
- if (x.lower) {
- lo = GetValue(*x.lower);
- }
- if (x.upper) {
- hi = GetValue(*x.upper);
- }
- if ((x.lower && !lo) || (x.upper && !hi)) {
- return PairOfValues{}; // error case
- }
- return PairOfValues{std::move(lo), std::move(hi)};
- },
- },
+ return common::visit(
+ common::visitors{
+ [&](const parser::CaseValue &x) {
+ auto value{GetValue(x)};
+ return PairOfValues{value, value};
+ },
+ [&](const parser::CaseValueRange::Range &x) {
+ std::optional<Value> lo, hi;
+ if (x.lower) {
+ lo = GetValue(*x.lower);
+ }
+ if (x.upper) {
+ hi = GetValue(*x.upper);
+ }
+ if ((x.lower && !lo) || (x.upper && !hi)) {
+ return PairOfValues{}; // error case
+ }
+ return PairOfValues{std::move(lo), std::move(hi)};
+ },
+ },
range.u);
}
diff --git a/flang/lib/Semantics/check-data.cpp b/flang/lib/Semantics/check-data.cpp
index a63e9b27d1928..955998bedc0c4 100644
--- a/flang/lib/Semantics/check-data.cpp
+++ b/flang/lib/Semantics/check-data.cpp
@@ -129,7 +129,7 @@ class DataVarChecker : public evaluate::AllTraverse<DataVarChecker, true> {
bool operator()(const evaluate::Subscript &subs) {
DataVarChecker subscriptChecker{context_, source_};
subscriptChecker.RestrictPointer();
- return std::visit(
+ return common::visit(
common::visitors{
[&](const evaluate::IndirectSubscriptIntegerExpr &expr) {
return CheckSubscriptExpr(expr);
@@ -205,18 +205,19 @@ void DataChecker::Leave(const parser::DataIDoObject &object) {
}
void DataChecker::Leave(const parser::DataStmtObject &dataObject) {
- std::visit(common::visitors{
- [](const parser::DataImpliedDo &) { // has own Enter()/Leave()
- },
- [&](const auto &var) {
- auto expr{exprAnalyzer_.Analyze(var)};
- if (!expr ||
- !DataVarChecker{exprAnalyzer_.context(),
- parser::FindSourceLocation(dataObject)}(*expr)) {
- currentSetHasFatalErrors_ = true;
- }
- },
- },
+ common::visit(
+ common::visitors{
+ [](const parser::DataImpliedDo &) { // has own Enter()/Leave()
+ },
+ [&](const auto &var) {
+ auto expr{exprAnalyzer_.Analyze(var)};
+ if (!expr ||
+ !DataVarChecker{exprAnalyzer_.context(),
+ parser::FindSourceLocation(dataObject)}(*expr)) {
+ currentSetHasFatalErrors_ = true;
+ }
+ },
+ },
dataObject.u);
}
diff --git a/flang/lib/Semantics/check-deallocate.cpp b/flang/lib/Semantics/check-deallocate.cpp
index bc8d123786cfc..d26935d283397 100644
--- a/flang/lib/Semantics/check-deallocate.cpp
+++ b/flang/lib/Semantics/check-deallocate.cpp
@@ -17,7 +17,7 @@ namespace Fortran::semantics {
void DeallocateChecker::Leave(const parser::DeallocateStmt &deallocateStmt) {
for (const parser::AllocateObject &allocateObject :
std::get<std::list<parser::AllocateObject>>(deallocateStmt.t)) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Name &name) {
auto const *symbol{name.symbol};
@@ -50,7 +50,7 @@ void DeallocateChecker::Leave(const parser::DeallocateStmt &deallocateStmt) {
bool gotStat{false}, gotMsg{false};
for (const parser::StatOrErrmsg &deallocOpt :
std::get<std::list<parser::StatOrErrmsg>>(deallocateStmt.t)) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::StatVariable &) {
if (gotStat) {
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 988557a7cdca5..ad999ed91a199 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -206,7 +206,7 @@ void CheckHelper::Check(const Symbol &symbol) {
const DeclTypeSpec *type{symbol.GetType()};
const DerivedTypeSpec *derived{type ? type->AsDerived() : nullptr};
bool isDone{false};
- std::visit(
+ common::visit(
common::visitors{
[&](const UseDetails &x) { isDone = true; },
[&](const HostAssocDetails &x) {
@@ -1145,17 +1145,17 @@ void CheckHelper::CheckHostAssoc(
void CheckHelper::CheckGeneric(
const Symbol &symbol, const GenericDetails &details) {
CheckSpecificsAreDistinguishable(symbol, details);
- std::visit(common::visitors{
- [&](const GenericKind::DefinedIo &io) {
- CheckDefinedIoProc(symbol, details, io);
- },
- [&](const GenericKind::OtherKind &other) {
- if (other == GenericKind::OtherKind::Name) {
- CheckGenericVsIntrinsic(symbol, details);
- }
- },
- [](const auto &) {},
- },
+ common::visit(common::visitors{
+ [&](const GenericKind::DefinedIo &io) {
+ CheckDefinedIoProc(symbol, details, io);
+ },
+ [&](const GenericKind::OtherKind &other) {
+ if (other == GenericKind::OtherKind::Name) {
+ CheckGenericVsIntrinsic(symbol, details);
+ }
+ },
+ [](const auto &) {},
+ },
details.kind().u);
}
@@ -1192,7 +1192,7 @@ static bool ConflictsWithIntrinsicOperator(
auto arg0{std::get<DummyDataObject>(proc.dummyArguments[0].u).type};
auto type0{arg0.type()};
if (proc.dummyArguments.size() == 1) { // unary
- return std::visit(
+ return common::visit(
common::visitors{
[&](common::NumericOperator) { return IsIntrinsicNumeric(type0); },
[&](common::LogicalOperator) { return IsIntrinsicLogical(type0); },
@@ -1204,7 +1204,7 @@ static bool ConflictsWithIntrinsicOperator(
auto arg1{std::get<DummyDataObject>(proc.dummyArguments[1].u).type};
auto type1{arg1.type()};
int rank1{arg1.Rank()};
- return std::visit(
+ return common::visit(
common::visitors{
[&](common::NumericOperator) {
return IsIntrinsicNumeric(type0, rank0, type1, rank1);
@@ -1268,27 +1268,27 @@ std::optional<parser::MessageFixedText> CheckHelper::CheckNumberOfArgs(
return std::nullopt;
}
std::size_t min{2}, max{2}; // allowed number of args; default is binary
- std::visit(common::visitors{
- [&](const common::NumericOperator &x) {
- if (x == common::NumericOperator::Add ||
- x == common::NumericOperator::Subtract) {
- min = 1; // + and - are unary or binary
- }
- },
- [&](const common::LogicalOperator &x) {
- if (x == common::LogicalOperator::Not) {
- min = 1; // .NOT. is unary
- max = 1;
- }
- },
- [](const common::RelationalOperator &) {
- // all are binary
- },
- [](const GenericKind::OtherKind &x) {
- CHECK(x == GenericKind::OtherKind::Concat);
- },
- [](const auto &) { DIE("expected intrinsic operator"); },
- },
+ common::visit(common::visitors{
+ [&](const common::NumericOperator &x) {
+ if (x == common::NumericOperator::Add ||
+ x == common::NumericOperator::Subtract) {
+ min = 1; // + and - are unary or binary
+ }
+ },
+ [&](const common::LogicalOperator &x) {
+ if (x == common::LogicalOperator::Not) {
+ min = 1; // .NOT. is unary
+ max = 1;
+ }
+ },
+ [](const common::RelationalOperator &) {
+ // all are binary
+ },
+ [](const GenericKind::OtherKind &x) {
+ CHECK(x == GenericKind::OtherKind::Concat);
+ },
+ [](const auto &) { DIE("expected intrinsic operator"); },
+ },
kind.u);
if (nargs >= min && nargs <= max) {
return std::nullopt;
@@ -2229,28 +2229,29 @@ void SubprogramMatchHelper::Check(
void SubprogramMatchHelper::CheckDummyArg(const Symbol &symbol1,
const Symbol &symbol2, const DummyArgument &arg1,
const DummyArgument &arg2) {
- std::visit(common::visitors{
- [&](const DummyDataObject &obj1, const DummyDataObject &obj2) {
- CheckDummyDataObject(symbol1, symbol2, obj1, obj2);
- },
- [&](const DummyProcedure &proc1, const DummyProcedure &proc2) {
- CheckDummyProcedure(symbol1, symbol2, proc1, proc2);
- },
- [&](const DummyDataObject &, const auto &) {
- Say(symbol1, symbol2,
- "Dummy argument '%s' is a data object; the corresponding"
- " argument in the interface body is not"_err_en_US);
- },
- [&](const DummyProcedure &, const auto &) {
- Say(symbol1, symbol2,
- "Dummy argument '%s' is a procedure; the corresponding"
- " argument in the interface body is not"_err_en_US);
- },
- [&](const auto &, const auto &) {
- llvm_unreachable("Dummy arguments are not data objects or"
- "procedures");
- },
- },
+ common::visit(
+ common::visitors{
+ [&](const DummyDataObject &obj1, const DummyDataObject &obj2) {
+ CheckDummyDataObject(symbol1, symbol2, obj1, obj2);
+ },
+ [&](const DummyProcedure &proc1, const DummyProcedure &proc2) {
+ CheckDummyProcedure(symbol1, symbol2, proc1, proc2);
+ },
+ [&](const DummyDataObject &, const auto &) {
+ Say(symbol1, symbol2,
+ "Dummy argument '%s' is a data object; the corresponding"
+ " argument in the interface body is not"_err_en_US);
+ },
+ [&](const DummyProcedure &, const auto &) {
+ Say(symbol1, symbol2,
+ "Dummy argument '%s' is a procedure; the corresponding"
+ " argument in the interface body is not"_err_en_US);
+ },
+ [&](const auto &, const auto &) {
+ llvm_unreachable("Dummy arguments are not data objects or"
+ "procedures");
+ },
+ },
arg1.u, arg2.u);
}
diff --git a/flang/lib/Semantics/check-do-forall.cpp b/flang/lib/Semantics/check-do-forall.cpp
index fada82df46d7b..3af15a68fd836 100644
--- a/flang/lib/Semantics/check-do-forall.cpp
+++ b/flang/lib/Semantics/check-do-forall.cpp
@@ -430,7 +430,7 @@ class DoContext {
}
void Check(const parser::ForallAssignmentStmt &stmt) {
- const evaluate::Assignment *assignment{std::visit(
+ const evaluate::Assignment *assignment{common::visit(
common::visitors{[&](const auto &x) { return GetAssignment(x); }},
stmt.u)};
if (assignment) {
@@ -441,23 +441,24 @@ class DoContext {
std::get_if<evaluate::ProcedureRef>(&assignment->u)}) {
CheckForImpureCall(*proc);
}
- std::visit(common::visitors{
- [](const evaluate::Assignment::Intrinsic &) {},
- [&](const evaluate::ProcedureRef &proc) {
- CheckForImpureCall(proc);
- },
- [&](const evaluate::Assignment::BoundsSpec &bounds) {
- for (const auto &bound : bounds) {
- CheckForImpureCall(SomeExpr{bound});
- }
- },
- [&](const evaluate::Assignment::BoundsRemapping &bounds) {
- for (const auto &bound : bounds) {
- CheckForImpureCall(SomeExpr{bound.first});
- CheckForImpureCall(SomeExpr{bound.second});
- }
- },
- },
+ common::visit(
+ common::visitors{
+ [](const evaluate::Assignment::Intrinsic &) {},
+ [&](const evaluate::ProcedureRef &proc) {
+ CheckForImpureCall(proc);
+ },
+ [&](const evaluate::Assignment::BoundsSpec &bounds) {
+ for (const auto &bound : bounds) {
+ CheckForImpureCall(SomeExpr{bound});
+ }
+ },
+ [&](const evaluate::Assignment::BoundsRemapping &bounds) {
+ for (const auto &bound : bounds) {
+ CheckForImpureCall(SomeExpr{bound.first});
+ CheckForImpureCall(SomeExpr{bound.second});
+ }
+ },
+ },
assignment->u);
}
}
@@ -737,7 +738,7 @@ class DoContext {
SymbolVector indexVars{context_.GetIndexVars(IndexVarKind::FORALL)};
if (!indexVars.empty()) {
UnorderedSymbolSet symbols{evaluate::CollectSymbols(assignment.lhs)};
- std::visit(
+ common::visit(
common::visitors{
[&](const evaluate::Assignment::BoundsSpec &spec) {
for (const auto &bound : spec) {
@@ -828,7 +829,7 @@ static parser::CharBlock GetConstructPosition(const A &a) {
}
static parser::CharBlock GetNodePosition(const ConstructNode &construct) {
- return std::visit(
+ return common::visit(
[&](const auto &x) { return GetConstructPosition(*x); }, construct);
}
@@ -859,24 +860,24 @@ static bool ConstructIsDoConcurrent(const ConstructNode &construct) {
// leave DO CONCURRENT, CRITICAL, or CHANGE TEAM constructs.
void DoForallChecker::CheckForBadLeave(
StmtType stmtType, const ConstructNode &construct) const {
- std::visit(common::visitors{
- [&](const parser::DoConstruct *doConstructPtr) {
- if (doConstructPtr->IsDoConcurrent()) {
- // C1135 and C1167 -- CYCLE and EXIT statements can't leave
- // a DO CONCURRENT
- SayBadLeave(stmtType, "DO CONCURRENT", construct);
- }
- },
- [&](const parser::CriticalConstruct *) {
- // C1135 and C1168 -- similarly, for CRITICAL
- SayBadLeave(stmtType, "CRITICAL", construct);
- },
- [&](const parser::ChangeTeamConstruct *) {
- // C1135 and C1168 -- similarly, for CHANGE TEAM
- SayBadLeave(stmtType, "CHANGE TEAM", construct);
- },
- [](const auto *) {},
- },
+ common::visit(common::visitors{
+ [&](const parser::DoConstruct *doConstructPtr) {
+ if (doConstructPtr->IsDoConcurrent()) {
+ // C1135 and C1167 -- CYCLE and EXIT statements can't
+ // leave a DO CONCURRENT
+ SayBadLeave(stmtType, "DO CONCURRENT", construct);
+ }
+ },
+ [&](const parser::CriticalConstruct *) {
+ // C1135 and C1168 -- similarly, for CRITICAL
+ SayBadLeave(stmtType, "CRITICAL", construct);
+ },
+ [&](const parser::ChangeTeamConstruct *) {
+ // C1135 and C1168 -- similarly, for CHANGE TEAM
+ SayBadLeave(stmtType, "CHANGE TEAM", construct);
+ },
+ [](const auto *) {},
+ },
construct);
}
diff --git a/flang/lib/Semantics/check-io.cpp b/flang/lib/Semantics/check-io.cpp
index 470ede163cfb7..01392eeb98604 100644
--- a/flang/lib/Semantics/check-io.cpp
+++ b/flang/lib/Semantics/check-io.cpp
@@ -204,7 +204,7 @@ void IoChecker::Enter(const parser::FileUnitNumber &) {
void IoChecker::Enter(const parser::Format &spec) {
SetSpecifier(IoSpecKind::Fmt);
flags_.set(Flag::FmtOrNml);
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Label &) { flags_.set(Flag::LabelFmt); },
[&](const parser::Star &) { flags_.set(Flag::StarFmt); },
diff --git a/flang/lib/Semantics/check-nullify.cpp b/flang/lib/Semantics/check-nullify.cpp
index 9ee45541fd5c5..6b3c8d4daf0fa 100644
--- a/flang/lib/Semantics/check-nullify.cpp
+++ b/flang/lib/Semantics/check-nullify.cpp
@@ -23,7 +23,7 @@ void NullifyChecker::Leave(const parser::NullifyStmt &nullifyStmt) {
parser::ContextualMessages messages{
*context_.location(), &context_.messages()};
for (const parser::PointerObject &pointerObject : nullifyStmt.v) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Name &name) {
const Symbol *symbol{name.symbol};
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 926cf35bb7480..cf56efb632d0f 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -262,7 +262,7 @@ void OmpStructureChecker::CheckPredefinedAllocatorRestriction(
const parser::CharBlock &source,
const parser::OmpObjectList &ompObjectList) {
for (const auto &ompObject : ompObjectList.v) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Designator &designator) {
if (const auto *dataRef{
@@ -420,54 +420,55 @@ void OmpStructureChecker::CheckSIMDNest(const parser::OpenMPConstruct &c) {
// current context yet.
// TODO: Check for declare simd regions.
bool eligibleSIMD{false};
- std::visit(Fortran::common::visitors{
- // Allow `!$OMP ORDERED SIMD`
- [&](const parser::OpenMPBlockConstruct &c) {
- const auto &beginBlockDir{
- std::get<parser::OmpBeginBlockDirective>(c.t)};
- const auto &beginDir{
- std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
- if (beginDir.v == llvm::omp::Directive::OMPD_ordered) {
- const auto &clauses{
- std::get<parser::OmpClauseList>(beginBlockDir.t)};
- for (const auto &clause : clauses.v) {
- if (std::get_if<parser::OmpClause::Simd>(&clause.u)) {
- eligibleSIMD = true;
- break;
- }
- }
- }
- },
- [&](const parser::OpenMPSimpleStandaloneConstruct &c) {
- const auto &dir{
- std::get<parser::OmpSimpleStandaloneDirective>(c.t)};
- if (dir.v == llvm::omp::Directive::OMPD_ordered) {
- const auto &clauses{std::get<parser::OmpClauseList>(c.t)};
- for (const auto &clause : clauses.v) {
- if (std::get_if<parser::OmpClause::Simd>(&clause.u)) {
- eligibleSIMD = true;
- break;
- }
- }
- }
- },
- // Allowing SIMD construct
- [&](const parser::OpenMPLoopConstruct &c) {
- const auto &beginLoopDir{
- std::get<parser::OmpBeginLoopDirective>(c.t)};
- const auto &beginDir{
- std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
- if ((beginDir.v == llvm::omp::Directive::OMPD_simd) ||
- (beginDir.v == llvm::omp::Directive::OMPD_do_simd)) {
- eligibleSIMD = true;
- }
- },
- [&](const parser::OpenMPAtomicConstruct &c) {
- // Allow `!$OMP ATOMIC`
- eligibleSIMD = true;
- },
- [&](const auto &c) {},
- },
+ common::visit(Fortran::common::visitors{
+ // Allow `!$OMP ORDERED SIMD`
+ [&](const parser::OpenMPBlockConstruct &c) {
+ const auto &beginBlockDir{
+ std::get<parser::OmpBeginBlockDirective>(c.t)};
+ const auto &beginDir{
+ std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
+ if (beginDir.v == llvm::omp::Directive::OMPD_ordered) {
+ const auto &clauses{
+ std::get<parser::OmpClauseList>(beginBlockDir.t)};
+ for (const auto &clause : clauses.v) {
+ if (std::get_if<parser::OmpClause::Simd>(&clause.u)) {
+ eligibleSIMD = true;
+ break;
+ }
+ }
+ }
+ },
+ [&](const parser::OpenMPSimpleStandaloneConstruct &c) {
+ const auto &dir{
+ std::get<parser::OmpSimpleStandaloneDirective>(c.t)};
+ if (dir.v == llvm::omp::Directive::OMPD_ordered) {
+ const auto &clauses{
+ std::get<parser::OmpClauseList>(c.t)};
+ for (const auto &clause : clauses.v) {
+ if (std::get_if<parser::OmpClause::Simd>(&clause.u)) {
+ eligibleSIMD = true;
+ break;
+ }
+ }
+ }
+ },
+ // Allowing SIMD construct
+ [&](const parser::OpenMPLoopConstruct &c) {
+ const auto &beginLoopDir{
+ std::get<parser::OmpBeginLoopDirective>(c.t)};
+ const auto &beginDir{
+ std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
+ if ((beginDir.v == llvm::omp::Directive::OMPD_simd) ||
+ (beginDir.v == llvm::omp::Directive::OMPD_do_simd)) {
+ eligibleSIMD = true;
+ }
+ },
+ [&](const parser::OpenMPAtomicConstruct &c) {
+ // Allow `!$OMP ATOMIC`
+ eligibleSIMD = true;
+ },
+ [&](const auto &c) {},
+ },
c.u);
if (!eligibleSIMD) {
context_.Say(parser::FindSourceLocation(c),
@@ -482,7 +483,7 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) {
// 2.12.5 Target Construct Restriction
bool eligibleTarget{true};
llvm::omp::Directive ineligibleTargetDir;
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::OpenMPBlockConstruct &c) {
const auto &beginBlockDir{
@@ -495,7 +496,7 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) {
}
},
[&](const parser::OpenMPStandaloneConstruct &c) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::OpenMPSimpleStandaloneConstruct &c) {
const auto &dir{
@@ -881,7 +882,7 @@ void OmpStructureChecker::Leave(const parser::OmpEndSectionsDirective &x) {
void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
const parser::OmpObjectList &objList) {
for (const auto &ompObject : objList.v) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Designator &) {
if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
@@ -1442,7 +1443,7 @@ void OmpStructureChecker::CheckAtomicUpdateAssignmentStmt(
const parser::AssignmentStmt &assignment) {
const auto &expr{std::get<parser::Expr>(assignment.t)};
const auto &var{std::get<parser::Variable>(assignment.t)};
- std::visit(
+ common::visit(
common::visitors{
[&](const common::Indirection<parser::FunctionReference> &x) {
const auto &procedureDesignator{
@@ -1542,7 +1543,7 @@ void OmpStructureChecker::CheckAtomicMemoryOrderClause(
}
void OmpStructureChecker::Enter(const parser::OpenMPAtomicConstruct &x) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::OmpAtomic &atomicConstruct) {
const auto &dir{std::get<parser::Verbatim>(atomicConstruct.t)};
@@ -1704,7 +1705,7 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
if (!threadprivateAllowedSet.test(type)) {
if (const auto *objList{GetOmpObjectList(*clause)}) {
for (const auto &ompObject : objList->v) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Designator &) {
if (const auto *name{
@@ -1831,7 +1832,7 @@ bool OmpStructureChecker::CheckReductionOperators(
const auto &definedOp{std::get<0>(x.v.t)};
bool ok = false;
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::DefinedOperator &dOpr) {
const auto &intrinsicOp{
@@ -2023,7 +2024,7 @@ void OmpStructureChecker::CheckIsVarPartOfAnotherVar(
llvm::omp::Directive::OMPD_threadprivate,
llvm::omp::Directive::OMPD_declare_target};
for (const auto &ompObject : objList.v) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Designator &designator) {
if (const auto *dataRef{
@@ -2360,7 +2361,7 @@ llvm::StringRef OmpStructureChecker::getDirectiveName(
}
void OmpStructureChecker::CheckDependList(const parser::DataRef &d) {
- std::visit(
+ common::visit(
common::visitors{
[&](const common::Indirection<parser::ArrayElement> &elem) {
// Check if the base element is valid on Depend Clause
@@ -2631,7 +2632,7 @@ const parser::OmpObjectList *OmpStructureChecker::GetOmpObjectList(
// TODO:: Generate the tuples using TableGen.
// Handle other constructs with OmpObjectList such as OpenMPThreadprivate.
- return std::visit(
+ return common::visit(
common::visitors{
[&](const auto &x) -> const parser::OmpObjectList * {
using Ty = std::decay_t<decltype(x)>;
diff --git a/flang/lib/Semantics/check-select-rank.cpp b/flang/lib/Semantics/check-select-rank.cpp
index d900584b414c7..ab8a1f3fb7788 100644
--- a/flang/lib/Semantics/check-select-rank.cpp
+++ b/flang/lib/Semantics/check-select-rank.cpp
@@ -60,7 +60,7 @@ void SelectRankConstructChecker::Leave(
std::get<parser::Statement<parser::SelectRankCaseStmt>>(rankCase.t)};
const auto &rank{
std::get<parser::SelectRankCaseStmt::Rank>(rankCaseStmt.statement.t)};
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Default &) { // C1153
if (!defaultRankFound) {
@@ -123,7 +123,7 @@ void SelectRankConstructChecker::Leave(
const SomeExpr *SelectRankConstructChecker::GetExprFromSelector(
const parser::Selector &selector) {
- return std::visit([](const auto &x) { return GetExpr(x); }, selector.u);
+ return common::visit([](const auto &x) { return GetExpr(x); }, selector.u);
}
} // namespace Fortran::semantics
diff --git a/flang/lib/Semantics/check-select-type.cpp b/flang/lib/Semantics/check-select-type.cpp
index af547ae77e2f5..aca687bae3863 100644
--- a/flang/lib/Semantics/check-select-type.cpp
+++ b/flang/lib/Semantics/check-select-type.cpp
@@ -51,7 +51,7 @@ class TypeCaseValues {
std::optional<evaluate::DynamicType> GetGuardType(
const parser::TypeGuardStmt::Guard &guard) {
- return std::visit(
+ return common::visit(
common::visitors{
[](const parser::Default &)
-> std::optional<evaluate::DynamicType> {
@@ -75,7 +75,7 @@ class TypeCaseValues {
const evaluate::DynamicType &guardDynamicType) {
const parser::TypeGuardStmt &typeGuardStmt{stmt.statement};
const auto &guard{std::get<parser::TypeGuardStmt::Guard>(typeGuardStmt.t)};
- return std::visit(
+ return common::visit(
common::visitors{
[](const parser::Default &) { return true; },
[&](const parser::TypeSpec &typeSpec) {
@@ -159,10 +159,10 @@ class TypeCaseValues {
void SetGuardType(std::optional<evaluate::DynamicType> guardTypeDynamic) {
const auto &guard{GetGuardFromStmt(stmt)};
- std::visit(common::visitors{
- [&](const parser::Default &) {},
- [&](const auto &) { guardType_ = *guardTypeDynamic; },
- },
+ common::visit(common::visitors{
+ [&](const parser::Default &) {},
+ [&](const auto &) { guardType_ = *guardTypeDynamic; },
+ },
guard.u);
}
@@ -268,6 +268,6 @@ void SelectTypeChecker::Enter(const parser::SelectTypeConstruct &construct) {
const SomeExpr *SelectTypeChecker::GetExprFromSelector(
const parser::Selector &selector) {
- return std::visit([](const auto &x) { return GetExpr(x); }, selector.u);
+ return common::visit([](const auto &x) { return GetExpr(x); }, selector.u);
}
} // namespace Fortran::semantics
diff --git a/flang/lib/Semantics/data-to-inits.cpp b/flang/lib/Semantics/data-to-inits.cpp
index d41de5ad234e4..86d45e27a58b6 100644
--- a/flang/lib/Semantics/data-to-inits.cpp
+++ b/flang/lib/Semantics/data-to-inits.cpp
@@ -123,7 +123,7 @@ class DataInitializationCompiler {
template <typename DSV>
bool DataInitializationCompiler<DSV>::Scan(
const parser::DataStmtObject &object) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const common::Indirection<parser::Variable> &var) {
return Scan(var.value());
@@ -218,7 +218,7 @@ bool DataInitializationCompiler<DSV>::Scan(const parser::DataImpliedDo &ido) {
template <typename DSV>
bool DataInitializationCompiler<DSV>::Scan(
const parser::DataIDoObject &object) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const parser::Scalar<common::Indirection<parser::Designator>>
&var) { return Scan(var.thing.value()); },
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index bb8e6a534d960..41c2492326d8c 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -288,7 +288,7 @@ MaybeExpr ExpressionAnalyzer::ApplySubscripts(
if (subscripts.empty()) {
return std::nullopt; // error recovery
}
- return std::visit(
+ return common::visit(
common::visitors{
[&](SymbolRef &&symbol) {
return CompleteSubscripts(ArrayRef{symbol, std::move(subscripts)});
@@ -337,7 +337,7 @@ static void FixMisparsedSubstring(const parser::Designator &d) {
if (!std::get<2>(triplet->t) /* no stride */ &&
++iter == arrElement.subscripts.end() /* one subscript */) {
if (Symbol *
- symbol{std::visit(
+ symbol{common::visit(
common::visitors{
[](parser::Name &n) { return n.symbol; },
[](common::Indirection<parser::StructureComponent>
@@ -397,7 +397,7 @@ int ExpressionAnalyzer::AnalyzeKindParam(
if (!kindParam) {
return defaultKind;
}
- return std::visit(
+ return common::visit(
common::visitors{
[](std::uint64_t k) { return static_cast<int>(k); },
[&](const parser::Scalar<
@@ -839,7 +839,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(
if (MaybeExpr string{Analyze(std::get<parser::CharLiteralConstant>(x.t))}) {
if (auto *charExpr{std::get_if<Expr<SomeCharacter>>(&string->u)}) {
Expr<SubscriptInteger> length{
- std::visit([](const auto &ckExpr) { return ckExpr.LEN().value(); },
+ common::visit([](const auto &ckExpr) { return ckExpr.LEN().value(); },
charExpr->u)};
if (!lower) {
lower = Expr<SubscriptInteger>{1};
@@ -848,7 +848,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(
upper = Expr<SubscriptInteger>{
static_cast<std::int64_t>(ToInt64(length).value())};
}
- return std::visit(
+ return common::visit(
[&](auto &&ckExpr) -> MaybeExpr {
using Result = ResultType<decltype(ckExpr)>;
auto *cp{std::get_if<Constant<Result>>(&ckExpr.u)};
@@ -902,7 +902,7 @@ std::optional<Expr<SubscriptInteger>> ExpressionAnalyzer::TripletPart(
std::optional<Subscript> ExpressionAnalyzer::AnalyzeSectionSubscript(
const parser::SectionSubscript &ss) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const parser::SubscriptTriplet &t) -> std::optional<Subscript> {
const auto &lower{std::get<0>(t.t)};
@@ -981,7 +981,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::ArrayElement &ae) {
// Type parameter inquiries apply to data references, but don't depend
// on any trailing (co)subscripts.
static NamedEntity IgnoreAnySubscripts(Designator<SomeDerived> &&designator) {
- return std::visit(
+ return common::visit(
common::visitors{
[](SymbolRef &&symbol) { return NamedEntity{symbol}; },
[](Component &&component) {
@@ -1074,7 +1074,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) {
if (kind == MiscKind::ComplexPartRe || kind == MiscKind::ComplexPartIm) {
if (auto *zExpr{std::get_if<Expr<SomeComplex>>(&base->u)}) {
if (std::optional<DataRef> dataRef{ExtractDataRef(std::move(*zExpr))}) {
- Expr<SomeReal> realExpr{std::visit(
+ Expr<SomeReal> realExpr{common::visit(
[&](const auto &z) {
using PartType = typename ResultType<decltype(z)>::Part;
auto part{kind == MiscKind::ComplexPartRe
@@ -1148,7 +1148,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::CoindexedNamedObject &x) {
}
for (const auto &imageSelSpec :
std::get<std::list<parser::ImageSelectorSpec>>(x.imageSelector.t)) {
- std::visit(
+ common::visit(
common::visitors{
[&](const auto &x) { Analyze(x.v); },
},
@@ -1185,7 +1185,7 @@ ArrayConstructorValues<T> MakeSpecific(
ArrayConstructorValues<SomeType> &&from) {
ArrayConstructorValues<T> to;
for (ArrayConstructorValue<SomeType> &x : from) {
- std::visit(
+ common::visit(
common::visitors{
[&](common::CopyableIndirection<Expr<SomeType>> &&expr) {
auto *typed{UnwrapExpr<Expr<T>>(expr.value())};
@@ -1334,7 +1334,7 @@ void ArrayConstructorContext::Push(MaybeExpr &&x) {
if (Expr<SomeCharacter> * charExpr{UnwrapExpr<Expr<SomeCharacter>>(*x)}) {
CHECK(xType.category() == TypeCategory::Character);
xType.length =
- std::visit([](const auto &kc) { return kc.LEN(); }, charExpr->u);
+ common::visit([](const auto &kc) { return kc.LEN(); }, charExpr->u);
}
if (!type_) {
// If there is no explicit type-spec in an array constructor, the type
@@ -1395,7 +1395,7 @@ void ArrayConstructorContext::Push(MaybeExpr &&x) {
}
void ArrayConstructorContext::Add(const parser::AcValue &x) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::AcValue::Triplet &triplet) { Add(triplet); },
[&](const common::Indirection<parser::Expr> &expr) {
@@ -1818,7 +1818,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(
static std::optional<parser::CharBlock> GetPassName(
const semantics::Symbol &proc) {
- return std::visit(
+ return common::visit(
[](const auto &details) {
if constexpr (std::is_base_of_v<semantics::WithPassArg,
std::decay_t<decltype(details)>>) {
@@ -1957,7 +1957,7 @@ auto ExpressionAnalyzer::AnalyzeProcedureComponentRef(
static bool CheckCompatibleArgument(bool isElemental,
const ActualArgument &actual, const characteristics::DummyArgument &dummy) {
const auto *expr{actual.UnwrapExpr()};
- return std::visit(
+ return common::visit(
common::visitors{
[&](const characteristics::DummyDataObject &x) {
if (x.attrs.test(characteristics::DummyDataObject::Attr::Pointer) &&
@@ -2152,7 +2152,7 @@ auto ExpressionAnalyzer::GetCalleeAndArguments(
const parser::ProcedureDesignator &pd, ActualArguments &&arguments,
bool isSubroutine, bool mightBeStructureConstructor)
-> std::optional<CalleeAndArguments> {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const parser::Name &name) {
return GetCalleeAndArguments(name, std::move(arguments),
@@ -2304,7 +2304,7 @@ static const Symbol *AssumedTypePointerOrAllocatableDummy(const A &object) {
// point it is is not guaranteed that it has been checked the object has
// POINTER or ALLOCATABLE attribute, so do not assume nullptr can be directly
// returned.
- return std::visit(
+ return common::visit(
common::visitors{
[&](const parser::StructureComponent &x) {
return AssumedTypeDummy(x.component);
@@ -2458,29 +2458,30 @@ const Assignment *ExpressionAnalyzer::Analyze(
new GenericAssignmentWrapper{}, GenericAssignmentWrapper::Deleter);
} else {
Assignment assignment{std::move(*lhs), std::move(*rhs)};
- std::visit(common::visitors{
- [&](const std::list<parser::BoundsRemapping> &list) {
- Assignment::BoundsRemapping bounds;
- for (const auto &elem : list) {
- auto lower{AsSubscript(Analyze(std::get<0>(elem.t)))};
- auto upper{AsSubscript(Analyze(std::get<1>(elem.t)))};
- if (lower && upper) {
- bounds.emplace_back(Fold(std::move(*lower)),
- Fold(std::move(*upper)));
- }
- }
- assignment.u = std::move(bounds);
- },
- [&](const std::list<parser::BoundsSpec> &list) {
- Assignment::BoundsSpec bounds;
- for (const auto &bound : list) {
- if (auto lower{AsSubscript(Analyze(bound.v))}) {
- bounds.emplace_back(Fold(std::move(*lower)));
- }
- }
- assignment.u = std::move(bounds);
- },
- },
+ common::visit(
+ common::visitors{
+ [&](const std::list<parser::BoundsRemapping> &list) {
+ Assignment::BoundsRemapping bounds;
+ for (const auto &elem : list) {
+ auto lower{AsSubscript(Analyze(std::get<0>(elem.t)))};
+ auto upper{AsSubscript(Analyze(std::get<1>(elem.t)))};
+ if (lower && upper) {
+ bounds.emplace_back(
+ Fold(std::move(*lower)), Fold(std::move(*upper)));
+ }
+ }
+ assignment.u = std::move(bounds);
+ },
+ [&](const std::list<parser::BoundsSpec> &list) {
+ Assignment::BoundsSpec bounds;
+ for (const auto &bound : list) {
+ if (auto lower{AsSubscript(Analyze(bound.v))}) {
+ bounds.emplace_back(Fold(std::move(*lower)));
+ }
+ }
+ assignment.u = std::move(bounds);
+ },
+ },
std::get<parser::PointerAssignmentStmt::Bounds>(x.t).u);
x.typedAssignment.Reset(
new GenericAssignmentWrapper{std::move(assignment)},
@@ -2690,7 +2691,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::Concat &x) {
if (!analyzer.fatalErrors()) {
if (analyzer.IsIntrinsicConcat()) {
analyzer.CheckForNullPointer();
- return std::visit(
+ return common::visit(
[&](auto &&x, auto &&y) -> MaybeExpr {
using T = ResultType<decltype(x)>;
if constexpr (std::is_same_v<T, ResultType<decltype(y)>>) {
@@ -2874,12 +2875,12 @@ static void FixMisparsedFunctionReference(
auto &proc{std::get<parser::ProcedureDesignator>(funcRef.v.t)};
if (Symbol *
origSymbol{
- std::visit(common::visitors{
- [&](parser::Name &name) { return name.symbol; },
- [&](parser::ProcComponentRef &pcr) {
- return pcr.v.thing.component.symbol;
- },
- },
+ common::visit(common::visitors{
+ [&](parser::Name &name) { return name.symbol; },
+ [&](parser::ProcComponentRef &pcr) {
+ return pcr.v.thing.component.symbol;
+ },
+ },
proc.u)}) {
Symbol &symbol{origSymbol->GetUltimate()};
if (symbol.has<semantics::ObjectEntityDetails>() ||
@@ -3023,7 +3024,7 @@ Expr<SubscriptInteger> ExpressionAnalyzer::AnalyzeKindSelector(
if (!selector) {
return Expr<SubscriptInteger>{defaultKind};
}
- return std::visit(
+ return common::visit(
common::visitors{
[&](const parser::ScalarIntConstantExpr &x) {
if (MaybeExpr kind{Analyze(x)}) {
@@ -3213,7 +3214,7 @@ void ArgumentAnalyzer::Analyze(
// be detected and represented (they're not expressions).
// TODO: C1534: Don't allow a "restricted" specific intrinsic to be passed.
std::optional<ActualArgument> actual;
- std::visit(
+ common::visit(
common::visitors{
[&](const common::Indirection<parser::Expr> &x) {
actual = AnalyzeExpr(x.value());
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index 8d1b095a02c3e..212e4c5d2f059 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -259,78 +259,79 @@ static llvm::raw_ostream &PutGenericName(
// procedures, type-bound generics, final procedures) which go to typeBindings.
void ModFileWriter::PutSymbol(
llvm::raw_ostream &typeBindings, const Symbol &symbol) {
- std::visit(common::visitors{
- [&](const ModuleDetails &) { /* should be current module */ },
- [&](const DerivedTypeDetails &) { PutDerivedType(symbol); },
- [&](const SubprogramDetails &) { PutSubprogram(symbol); },
- [&](const GenericDetails &x) {
- if (symbol.owner().IsDerivedType()) {
- // generic binding
- for (const Symbol &proc : x.specificProcs()) {
- PutGenericName(typeBindings << "generic::", symbol)
- << "=>" << proc.name() << '\n';
- }
- } else {
- PutGeneric(symbol);
- if (x.specific()) {
- PutSymbol(typeBindings, *x.specific());
- }
- if (x.derivedType()) {
- PutSymbol(typeBindings, *x.derivedType());
- }
- }
- },
- [&](const UseDetails &) { PutUse(symbol); },
- [](const UseErrorDetails &) {},
- [&](const ProcBindingDetails &x) {
- bool deferred{symbol.attrs().test(Attr::DEFERRED)};
- typeBindings << "procedure";
- if (deferred) {
- typeBindings << '(' << x.symbol().name() << ')';
- }
- PutPassName(typeBindings, x.passName());
- auto attrs{symbol.attrs()};
- if (x.passName()) {
- attrs.reset(Attr::PASS);
- }
- PutAttrs(typeBindings, attrs);
- typeBindings << "::" << symbol.name();
- if (!deferred && x.symbol().name() != symbol.name()) {
- typeBindings << "=>" << x.symbol().name();
- }
- typeBindings << '\n';
- },
- [&](const NamelistDetails &x) {
- decls_ << "namelist/" << symbol.name();
- char sep{'/'};
- for (const Symbol &object : x.objects()) {
- decls_ << sep << object.name();
- sep = ',';
- }
- decls_ << '\n';
- },
- [&](const CommonBlockDetails &x) {
- decls_ << "common/" << symbol.name();
- char sep = '/';
- for (const auto &object : x.objects()) {
- decls_ << sep << object->name();
- sep = ',';
- }
- decls_ << '\n';
- if (symbol.attrs().test(Attr::BIND_C)) {
- PutAttrs(decls_, symbol.attrs(), x.bindName(), ""s);
- decls_ << "::/" << symbol.name() << "/\n";
- }
- },
- [](const HostAssocDetails &) {},
- [](const MiscDetails &) {},
- [&](const auto &) {
- PutEntity(decls_, symbol);
- if (symbol.test(Symbol::Flag::OmpThreadprivate)) {
- decls_ << "!$omp threadprivate(" << symbol.name() << ")\n";
- }
- },
- },
+ common::visit(
+ common::visitors{
+ [&](const ModuleDetails &) { /* should be current module */ },
+ [&](const DerivedTypeDetails &) { PutDerivedType(symbol); },
+ [&](const SubprogramDetails &) { PutSubprogram(symbol); },
+ [&](const GenericDetails &x) {
+ if (symbol.owner().IsDerivedType()) {
+ // generic binding
+ for (const Symbol &proc : x.specificProcs()) {
+ PutGenericName(typeBindings << "generic::", symbol)
+ << "=>" << proc.name() << '\n';
+ }
+ } else {
+ PutGeneric(symbol);
+ if (x.specific()) {
+ PutSymbol(typeBindings, *x.specific());
+ }
+ if (x.derivedType()) {
+ PutSymbol(typeBindings, *x.derivedType());
+ }
+ }
+ },
+ [&](const UseDetails &) { PutUse(symbol); },
+ [](const UseErrorDetails &) {},
+ [&](const ProcBindingDetails &x) {
+ bool deferred{symbol.attrs().test(Attr::DEFERRED)};
+ typeBindings << "procedure";
+ if (deferred) {
+ typeBindings << '(' << x.symbol().name() << ')';
+ }
+ PutPassName(typeBindings, x.passName());
+ auto attrs{symbol.attrs()};
+ if (x.passName()) {
+ attrs.reset(Attr::PASS);
+ }
+ PutAttrs(typeBindings, attrs);
+ typeBindings << "::" << symbol.name();
+ if (!deferred && x.symbol().name() != symbol.name()) {
+ typeBindings << "=>" << x.symbol().name();
+ }
+ typeBindings << '\n';
+ },
+ [&](const NamelistDetails &x) {
+ decls_ << "namelist/" << symbol.name();
+ char sep{'/'};
+ for (const Symbol &object : x.objects()) {
+ decls_ << sep << object.name();
+ sep = ',';
+ }
+ decls_ << '\n';
+ },
+ [&](const CommonBlockDetails &x) {
+ decls_ << "common/" << symbol.name();
+ char sep = '/';
+ for (const auto &object : x.objects()) {
+ decls_ << sep << object->name();
+ sep = ',';
+ }
+ decls_ << '\n';
+ if (symbol.attrs().test(Attr::BIND_C)) {
+ PutAttrs(decls_, symbol.attrs(), x.bindName(), ""s);
+ decls_ << "::/" << symbol.name() << "/\n";
+ }
+ },
+ [](const HostAssocDetails &) {},
+ [](const MiscDetails &) {},
+ [&](const auto &) {
+ PutEntity(decls_, symbol);
+ if (symbol.test(Symbol::Flag::OmpThreadprivate)) {
+ decls_ << "!$omp threadprivate(" << symbol.name() << ")\n";
+ }
+ },
+ },
symbol.details());
}
@@ -601,7 +602,7 @@ void CollectSymbols(
}
void ModFileWriter::PutEntity(llvm::raw_ostream &os, const Symbol &symbol) {
- std::visit(
+ common::visit(
common::visitors{
[&](const ObjectEntityDetails &) { PutObjectEntity(os, symbol); },
[&](const ProcEntityDetails &) { PutProcEntity(os, symbol); },
@@ -1114,27 +1115,27 @@ void SubprogramSymbolCollector::DoSymbol(
if (!needSet_.insert(symbol).second) {
return; // already done
}
- std::visit(common::visitors{
- [this](const ObjectEntityDetails &details) {
- for (const ShapeSpec &spec : details.shape()) {
- DoBound(spec.lbound());
- DoBound(spec.ubound());
- }
- for (const ShapeSpec &spec : details.coshape()) {
- DoBound(spec.lbound());
- DoBound(spec.ubound());
- }
- if (const Symbol * commonBlock{details.commonBlock()}) {
- DoSymbol(*commonBlock);
- }
- },
- [this](const CommonBlockDetails &details) {
- for (const auto &object : details.objects()) {
- DoSymbol(*object);
- }
- },
- [](const auto &) {},
- },
+ common::visit(common::visitors{
+ [this](const ObjectEntityDetails &details) {
+ for (const ShapeSpec &spec : details.shape()) {
+ DoBound(spec.lbound());
+ DoBound(spec.ubound());
+ }
+ for (const ShapeSpec &spec : details.coshape()) {
+ DoBound(spec.lbound());
+ DoBound(spec.ubound());
+ }
+ if (const Symbol * commonBlock{details.commonBlock()}) {
+ DoSymbol(*commonBlock);
+ }
+ },
+ [this](const CommonBlockDetails &details) {
+ for (const auto &object : details.objects()) {
+ DoSymbol(*object);
+ }
+ },
+ [](const auto &) {},
+ },
symbol.details());
if (!symbol.has<UseDetails>()) {
DoType(symbol.GetType());
diff --git a/flang/lib/Semantics/pointer-assignment.cpp b/flang/lib/Semantics/pointer-assignment.cpp
index 2b065253bdc70..d55fa16001335 100644
--- a/flang/lib/Semantics/pointer-assignment.cpp
+++ b/flang/lib/Semantics/pointer-assignment.cpp
@@ -117,7 +117,7 @@ template <typename T> bool PointerAssignmentChecker::Check(const T &) {
template <typename T>
bool PointerAssignmentChecker::Check(const evaluate::Expr<T> &x) {
- return std::visit([&](const auto &x) { return Check(x); }, x.u);
+ return common::visit([&](const auto &x) { return Check(x); }, x.u);
}
bool PointerAssignmentChecker::Check(const SomeExpr &rhs) {
@@ -128,7 +128,7 @@ bool PointerAssignmentChecker::Check(const SomeExpr &rhs) {
Say("A coindexed object may not be a pointer target"_err_en_US);
return false;
} else {
- return std::visit([&](const auto &x) { return Check(x); }, rhs.u);
+ return common::visit([&](const auto &x) { return Check(x); }, rhs.u);
}
}
@@ -322,7 +322,7 @@ static bool CheckPointerBounds(
const SomeExpr &lhs{assignment.lhs};
const SomeExpr &rhs{assignment.rhs};
bool isBoundsRemapping{false};
- std::size_t numBounds{std::visit(
+ std::size_t numBounds{common::visit(
common::visitors{
[&](const evaluate::Assignment::BoundsSpec &bounds) {
return bounds.size();
diff --git a/flang/lib/Semantics/program-tree.cpp b/flang/lib/Semantics/program-tree.cpp
index 9d76cfad83805..e96a6c4c07d82 100644
--- a/flang/lib/Semantics/program-tree.cpp
+++ b/flang/lib/Semantics/program-tree.cpp
@@ -88,7 +88,7 @@ static ProgramTree BuildSubprogramTree(const parser::Name &name, const T &x) {
if (subps) {
for (const auto &subp :
std::get<std::list<parser::InternalSubprogram>>(subps->t)) {
- std::visit(
+ common::visit(
[&](const auto &y) { node.AddChild(ProgramTree::Build(y.value())); },
subp.u);
}
@@ -111,7 +111,7 @@ static ProgramTree BuildModuleTree(const parser::Name &name, const T &x) {
if (subps) {
for (const auto &subp :
std::get<std::list<parser::ModuleSubprogram>>(subps->t)) {
- std::visit(
+ common::visit(
[&](const auto &y) { node.AddChild(ProgramTree::Build(y.value())); },
subp.u);
}
@@ -120,7 +120,7 @@ static ProgramTree BuildModuleTree(const parser::Name &name, const T &x) {
}
ProgramTree ProgramTree::Build(const parser::ProgramUnit &x) {
- return std::visit([](const auto &y) { return Build(y.value()); }, x.u);
+ return common::visit([](const auto &y) { return Build(y.value()); }, x.u);
}
ProgramTree ProgramTree::Build(const parser::MainProgram &x) {
@@ -200,17 +200,17 @@ Symbol::Flag ProgramTree::GetSubpFlag() const {
bool ProgramTree::HasModulePrefix() const {
using ListType = std::list<parser::PrefixSpec>;
- const auto *prefixes{
- std::visit(common::visitors{
- [](const parser::Statement<parser::FunctionStmt> *x) {
- return &std::get<ListType>(x->statement.t);
- },
- [](const parser::Statement<parser::SubroutineStmt> *x) {
- return &std::get<ListType>(x->statement.t);
- },
- [](const auto *) -> const ListType * { return nullptr; },
- },
- stmt_)};
+ const auto *prefixes{common::visit(
+ common::visitors{
+ [](const parser::Statement<parser::FunctionStmt> *x) {
+ return &std::get<ListType>(x->statement.t);
+ },
+ [](const parser::Statement<parser::SubroutineStmt> *x) {
+ return &std::get<ListType>(x->statement.t);
+ },
+ [](const auto *) -> const ListType * { return nullptr; },
+ },
+ stmt_)};
if (prefixes) {
for (const auto &prefix : *prefixes) {
if (std::holds_alternative<parser::PrefixSpec::Module>(prefix.u)) {
@@ -222,7 +222,7 @@ bool ProgramTree::HasModulePrefix() const {
}
ProgramTree::Kind ProgramTree::GetKind() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](const parser::Statement<parser::ProgramStmt> *) {
return Kind::Program;
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 2af91517a43d7..99e59f7fc7af8 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -364,18 +364,18 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
return false;
}
bool Pre(const parser::OmpLinearClause &x) {
- std::visit(common::visitors{
- [&](const parser::OmpLinearClause::WithoutModifier
- &linearWithoutModifier) {
- ResolveOmpNameList(
- linearWithoutModifier.names, Symbol::Flag::OmpLinear);
- },
- [&](const parser::OmpLinearClause::WithModifier
- &linearWithModifier) {
- ResolveOmpNameList(
- linearWithModifier.names, Symbol::Flag::OmpLinear);
- },
- },
+ common::visit(common::visitors{
+ [&](const parser::OmpLinearClause::WithoutModifier
+ &linearWithoutModifier) {
+ ResolveOmpNameList(linearWithoutModifier.names,
+ Symbol::Flag::OmpLinear);
+ },
+ [&](const parser::OmpLinearClause::WithModifier
+ &linearWithModifier) {
+ ResolveOmpNameList(
+ linearWithModifier.names, Symbol::Flag::OmpLinear);
+ },
+ },
x.u);
return false;
}
@@ -756,7 +756,7 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCCombinedConstruct &x) {
static bool IsLastNameArray(const parser::Designator &designator) {
const auto &name{GetLastName(designator)};
const evaluate::DataRef dataRef{*(name.symbol)};
- return std::visit(
+ return common::visit(
common::visitors{
[](const evaluate::SymbolRef &ref) { return ref->Rank() > 0; },
[](const evaluate::ArrayRef &aref) {
@@ -771,7 +771,7 @@ static bool IsLastNameArray(const parser::Designator &designator) {
void AccAttributeVisitor::AllowOnlyArrayAndSubArray(
const parser::AccObjectList &objectList) {
for (const auto &accObject : objectList.v) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Designator &designator) {
if (!IsLastNameArray(designator)) {
@@ -798,7 +798,7 @@ void AccAttributeVisitor::AllowOnlyArrayAndSubArray(
void AccAttributeVisitor::DoNotAllowAssumedSizedArray(
const parser::AccObjectList &objectList) {
for (const auto &accObject : objectList.v) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Designator &designator) {
const auto &name{GetLastName(designator)};
@@ -883,7 +883,7 @@ void AccAttributeVisitor::PrivatizeAssociatedLoopIndex(
void AccAttributeVisitor::EnsureAllocatableOrPointer(
const llvm::acc::Clause clause, const parser::AccObjectList &objectList) {
for (const auto &accObject : objectList.v) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Designator &designator) {
const auto &lastName{GetLastName(designator)};
@@ -977,7 +977,7 @@ void AccAttributeVisitor::ResolveAccObjectList(
void AccAttributeVisitor::ResolveAccObject(
const parser::AccObject &accObject, Symbol::Flag accFlag) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Designator &designator) {
if (const auto *name{GetDesignatorNameIfDataRef(designator)}) {
@@ -1572,7 +1572,7 @@ void OmpAttributeVisitor::ResolveOmpObjectList(
void OmpAttributeVisitor::ResolveOmpObject(
const parser::OmpObject &ompObject, Symbol::Flag ompFlag) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Designator &designator) {
if (const auto *name{GetDesignatorNameIfDataRef(designator)}) {
diff --git a/flang/lib/Semantics/resolve-names-utils.cpp b/flang/lib/Semantics/resolve-names-utils.cpp
index 2d8f2c16bb8b3..7aab69401bb48 100644
--- a/flang/lib/Semantics/resolve-names-utils.cpp
+++ b/flang/lib/Semantics/resolve-names-utils.cpp
@@ -126,7 +126,7 @@ void GenericSpecInfo::Analyze(const parser::DefinedOpName &name) {
void GenericSpecInfo::Analyze(const parser::GenericSpec &x) {
symbolName_ = x.source;
- kind_ = std::visit(
+ kind_ = common::visit(
common::visitors{
[&](const parser::Name &y) -> GenericKind {
parseName_ = &y;
@@ -134,7 +134,7 @@ void GenericSpecInfo::Analyze(const parser::GenericSpec &x) {
return GenericKind::OtherKind::Name;
},
[&](const parser::DefinedOperator &y) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const parser::DefinedOpName &z) -> GenericKind {
Analyze(z);
@@ -265,19 +265,20 @@ ArraySpec AnalyzeCoarraySpec(
}
ArraySpec ArraySpecAnalyzer::Analyze(const parser::ComponentArraySpec &x) {
- std::visit([this](const auto &y) { Analyze(y); }, x.u);
+ common::visit([this](const auto &y) { Analyze(y); }, x.u);
CHECK(!arraySpec_.empty());
return arraySpec_;
}
ArraySpec ArraySpecAnalyzer::Analyze(const parser::ArraySpec &x) {
- std::visit(common::visitors{
- [&](const parser::AssumedSizeSpec &y) {
- Analyze(std::get<std::list<parser::ExplicitShapeSpec>>(y.t));
- Analyze(std::get<parser::AssumedImpliedSpec>(y.t));
- },
- [&](const parser::ImpliedShapeSpec &y) { Analyze(y.v); },
- [&](const auto &y) { Analyze(y); },
- },
+ common::visit(common::visitors{
+ [&](const parser::AssumedSizeSpec &y) {
+ Analyze(
+ std::get<std::list<parser::ExplicitShapeSpec>>(y.t));
+ Analyze(std::get<parser::AssumedImpliedSpec>(y.t));
+ },
+ [&](const parser::ImpliedShapeSpec &y) { Analyze(y.v); },
+ [&](const auto &y) { Analyze(y); },
+ },
x.u);
CHECK(!arraySpec_.empty());
return arraySpec_;
@@ -289,7 +290,7 @@ ArraySpec ArraySpecAnalyzer::AnalyzeDeferredShapeSpecList(
return arraySpec_;
}
ArraySpec ArraySpecAnalyzer::Analyze(const parser::CoarraySpec &x) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::DeferredCoshapeSpecList &y) { MakeDeferred(y.v); },
[&](const parser::ExplicitCoshapeSpec &y) {
@@ -495,7 +496,7 @@ const EquivalenceObject *EquivalenceSets::Find(
}
bool EquivalenceSets::CheckDesignator(const parser::Designator &designator) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const parser::DataRef &x) {
return CheckDataRef(designator.source, x);
@@ -520,7 +521,7 @@ bool EquivalenceSets::CheckDesignator(const parser::Designator &designator) {
bool EquivalenceSets::CheckDataRef(
const parser::CharBlock &source, const parser::DataRef &x) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const parser::Name &name) { return CheckObject(name); },
[&](const common::Indirection<parser::StructureComponent> &) {
@@ -532,7 +533,7 @@ bool EquivalenceSets::CheckDataRef(
[&](const common::Indirection<parser::ArrayElement> &elem) {
bool ok{CheckDataRef(source, elem.value().base)};
for (const auto &subscript : elem.value().subscripts) {
- ok &= std::visit(
+ ok &= common::visit(
common::visitors{
[&](const parser::SubscriptTriplet &) {
context_.Say(source, // C924, R872
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 8fd25bd8cdd9c..35a8c353fcb2f 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -17,6 +17,7 @@
#include "flang/Common/default-kinds.h"
#include "flang/Common/indirection.h"
#include "flang/Common/restorer.h"
+#include "flang/Common/visit.h"
#include "flang/Evaluate/characteristics.h"
#include "flang/Evaluate/check-expression.h"
#include "flang/Evaluate/common.h"
@@ -1633,11 +1634,11 @@ bool AttrsVisitor::SetPassNameOn(Symbol &symbol) {
if (!passName_) {
return false;
}
- std::visit(common::visitors{
- [&](ProcEntityDetails &x) { x.set_passName(*passName_); },
- [&](ProcBindingDetails &x) { x.set_passName(*passName_); },
- [](auto &) { common::die("unexpected pass name"); },
- },
+ common::visit(common::visitors{
+ [&](ProcEntityDetails &x) { x.set_passName(*passName_); },
+ [&](ProcBindingDetails &x) { x.set_passName(*passName_); },
+ [](auto &) { common::die("unexpected pass name"); },
+ },
symbol.details());
return true;
}
@@ -1841,20 +1842,20 @@ void ImplicitRulesVisitor::Post(const parser::ParameterStmt &) {
bool ImplicitRulesVisitor::Pre(const parser::ImplicitStmt &x) {
bool result{
- std::visit(common::visitors{
- [&](const std::list<ImplicitNoneNameSpec> &y) {
- return HandleImplicitNone(y);
- },
- [&](const std::list<parser::ImplicitSpec> &) {
- if (prevImplicitNoneType_) {
- Say("IMPLICIT statement after IMPLICIT NONE or "
- "IMPLICIT NONE(TYPE) statement"_err_en_US);
- return false;
- }
- implicitRules_->set_isImplicitNoneType(false);
- return true;
- },
- },
+ common::visit(common::visitors{
+ [&](const std::list<ImplicitNoneNameSpec> &y) {
+ return HandleImplicitNone(y);
+ },
+ [&](const std::list<parser::ImplicitSpec> &) {
+ if (prevImplicitNoneType_) {
+ Say("IMPLICIT statement after IMPLICIT NONE or "
+ "IMPLICIT NONE(TYPE) statement"_err_en_US);
+ return false;
+ }
+ implicitRules_->set_isImplicitNoneType(false);
+ return true;
+ },
+ },
x.u)};
prevImplicit_ = currStmtSource();
return result;
@@ -2288,17 +2289,17 @@ void ScopeHandler::EraseSymbol(const parser::Name &name) {
static bool NeedsType(const Symbol &symbol) {
return !symbol.GetType() &&
- std::visit(common::visitors{
- [](const EntityDetails &) { return true; },
- [](const ObjectEntityDetails &) { return true; },
- [](const AssocEntityDetails &) { return true; },
- [&](const ProcEntityDetails &p) {
- return symbol.test(Symbol::Flag::Function) &&
- !symbol.attrs().test(Attr::INTRINSIC) &&
- !p.interface().type() && !p.interface().symbol();
- },
- [](const auto &) { return false; },
- },
+ common::visit(common::visitors{
+ [](const EntityDetails &) { return true; },
+ [](const ObjectEntityDetails &) { return true; },
+ [](const AssocEntityDetails &) { return true; },
+ [&](const ProcEntityDetails &p) {
+ return symbol.test(Symbol::Flag::Function) &&
+ !symbol.attrs().test(Attr::INTRINSIC) &&
+ !p.interface().type() && !p.interface().symbol();
+ },
+ [](const auto &) { return false; },
+ },
symbol.details());
}
@@ -2529,18 +2530,18 @@ void ScopeHandler::MakeExternal(Symbol &symbol) {
// ModuleVisitor implementation
bool ModuleVisitor::Pre(const parser::Only &x) {
- std::visit(common::visitors{
- [&](const Indirection<parser::GenericSpec> &generic) {
- GenericSpecInfo genericSpecInfo{generic.value()};
- AddUseOnly(genericSpecInfo.symbolName());
- AddUse(genericSpecInfo);
- },
- [&](const parser::Name &name) {
- AddUseOnly(name.source);
- Resolve(name, AddUse(name.source, name.source).use);
- },
- [&](const parser::Rename &rename) { Walk(rename); },
- },
+ common::visit(common::visitors{
+ [&](const Indirection<parser::GenericSpec> &generic) {
+ GenericSpecInfo genericSpecInfo{generic.value()};
+ AddUseOnly(genericSpecInfo.symbolName());
+ AddUse(genericSpecInfo);
+ },
+ [&](const parser::Name &name) {
+ AddUseOnly(name.source);
+ Resolve(name, AddUse(name.source, name.source).use);
+ },
+ [&](const parser::Rename &rename) { Walk(rename); },
+ },
x.u);
return false;
}
@@ -2605,14 +2606,14 @@ void ModuleVisitor::Post(const parser::UseStmt &x) {
// then add a use for each public name that was not renamed.
std::set<SourceName> useNames;
for (const auto &rename : *list) {
- std::visit(common::visitors{
- [&](const parser::Rename::Names &names) {
- useNames.insert(std::get<1>(names.t).source);
- },
- [&](const parser::Rename::Operators &ops) {
- useNames.insert(std::get<1>(ops.t).v.source);
- },
- },
+ common::visit(common::visitors{
+ [&](const parser::Rename::Names &names) {
+ useNames.insert(std::get<1>(names.t).source);
+ },
+ [&](const parser::Rename::Operators &ops) {
+ useNames.insert(std::get<1>(ops.t).v.source);
+ },
+ },
rename.u);
}
for (const auto &[name, symbol] : *useModuleScope_) {
@@ -3356,7 +3357,7 @@ void SubprogramVisitor::Post(const parser::EntryStmt &stmt) {
auto &effectiveResultName{*(resultName ? resultName : &name)};
resultSymbol = FindInScope(currScope(), effectiveResultName);
if (resultSymbol) { // C1574
- std::visit(
+ common::visit(
common::visitors{[](EntityDetails &x) { x.set_funcResult(true); },
[](ObjectEntityDetails &x) { x.set_funcResult(true); },
[](ProcEntityDetails &x) { x.set_funcResult(true); },
@@ -3387,7 +3388,7 @@ void SubprogramVisitor::Post(const parser::EntryStmt &stmt) {
if (const auto *dummyName{std::get_if<parser::Name>(&dummyArg.u)}) {
Symbol *dummy{FindSymbol(*dummyName)};
if (dummy) {
- std::visit(
+ common::visit(
common::visitors{[](EntityDetails &x) { x.set_isDummy(); },
[](ObjectEntityDetails &x) { x.set_isDummy(); },
[](ProcEntityDetails &x) { x.set_isDummy(); },
@@ -5653,7 +5654,7 @@ bool DeclarationVisitor::OkToAddComponent(
ParamValue DeclarationVisitor::GetParamValue(
const parser::TypeParamValue &x, common::TypeParamAttr attr) {
- return std::visit(
+ return common::visit(
common::visitors{
[=](const parser::ScalarIntExpr &x) { // C704
return ParamValue{EvaluateIntExpr(x), attr};
@@ -5812,7 +5813,7 @@ bool ConstructVisitor::Pre(const parser::DataImpliedDo &x) {
// statement so that the predicate IsInitialized() will be true
// during semantic analysis before the symbol's initializer is constructed.
bool ConstructVisitor::Pre(const parser::DataIDoObject &x) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Scalar<Indirection<parser::Designator>> &y) {
Walk(y.thing.value());
@@ -5828,20 +5829,21 @@ bool ConstructVisitor::Pre(const parser::DataIDoObject &x) {
}
bool ConstructVisitor::Pre(const parser::DataStmtObject &x) {
- std::visit(common::visitors{
- [&](const Indirection<parser::Variable> &y) {
- Walk(y.value());
- const parser::Name &first{parser::GetFirstName(y.value())};
- if (first.symbol) {
- first.symbol->set(Symbol::Flag::InDataStmt);
- }
- },
- [&](const parser::DataImpliedDo &y) {
- PushScope(Scope::Kind::ImpliedDos, nullptr);
- Walk(y);
- PopScope();
- },
- },
+ common::visit(common::visitors{
+ [&](const Indirection<parser::Variable> &y) {
+ Walk(y.value());
+ const parser::Name &first{
+ parser::GetFirstName(y.value())};
+ if (first.symbol) {
+ first.symbol->set(Symbol::Flag::InDataStmt);
+ }
+ },
+ [&](const parser::DataImpliedDo &y) {
+ PushScope(Scope::Kind::ImpliedDos, nullptr);
+ Walk(y);
+ PopScope();
+ },
+ },
x.u);
return false;
}
@@ -6121,9 +6123,9 @@ void ConstructVisitor::SetTypeFromAssociation(Symbol &symbol) {
evaluate::UnwrapExpr<evaluate::Expr<evaluate::SomeCharacter>>(
expr)}) {
symbol.SetType(ToDeclTypeSpec(std::move(*type),
- FoldExpr(
- std::visit([](const auto &kindChar) { return kindChar.LEN(); },
- charExpr->u))));
+ FoldExpr(common::visit(
+ [](const auto &kindChar) { return kindChar.LEN(); },
+ charExpr->u))));
} else {
symbol.SetType(ToDeclTypeSpec(std::move(*type)));
}
@@ -6146,14 +6148,14 @@ void ConstructVisitor::SetAttrsFromAssociation(Symbol &symbol) {
ConstructVisitor::Selector ConstructVisitor::ResolveSelector(
const parser::Selector &x) {
- return std::visit(common::visitors{
- [&](const parser::Expr &expr) {
- return Selector{expr.source, EvaluateExpr(x)};
- },
- [&](const parser::Variable &var) {
- return Selector{var.GetSource(), EvaluateExpr(x)};
- },
- },
+ return common::visit(common::visitors{
+ [&](const parser::Expr &expr) {
+ return Selector{expr.source, EvaluateExpr(x)};
+ },
+ [&](const parser::Variable &var) {
+ return Selector{var.GetSource(), EvaluateExpr(x)};
+ },
+ },
x.u);
}
@@ -6283,7 +6285,7 @@ const parser::Name *DeclarationVisitor::ResolveStructureComponent(
const parser::Name *DeclarationVisitor::ResolveDesignator(
const parser::Designator &x) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const parser::DataRef &x) { return ResolveDataRef(x); },
[&](const parser::Substring &x) {
@@ -6295,7 +6297,7 @@ const parser::Name *DeclarationVisitor::ResolveDesignator(
const parser::Name *DeclarationVisitor::ResolveDataRef(
const parser::DataRef &x) {
- return std::visit(
+ return common::visit(
common::visitors{
[=](const parser::Name &y) { return ResolveName(y); },
[=](const Indirection<parser::StructureComponent> &y) {
@@ -6514,7 +6516,7 @@ void DeclarationVisitor::Initialization(const parser::Name &name,
if (auto *object{ultimate.detailsIf<ObjectEntityDetails>()}) {
// TODO: check C762 - all bounds and type parameters of component
// are colons or constant expressions if component is initialized
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::ConstantExpr &expr) {
NonPointerInitialization(name, expr);
@@ -6624,7 +6626,7 @@ void DeclarationVisitor::NonPointerInitialization(
void ResolveNamesVisitor::HandleCall(
Symbol::Flag procFlag, const parser::Call &call) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Name &x) { HandleProcedureName(procFlag, x); },
[&](const parser::ProcComponentRef &x) { Walk(x); },
@@ -6803,7 +6805,7 @@ bool ModuleVisitor::Pre(const parser::AccessStmt &x) {
defaultAccess_ = accessAttr;
} else {
for (const auto &accessId : accessIds) {
- std::visit(
+ common::visit(
common::visitors{
[=](const parser::Name &y) {
Resolve(y, SetAccess(y.source, accessAttr));
@@ -6890,7 +6892,7 @@ bool ResolveNamesVisitor::Pre(const parser::SpecificationPart &x) {
// Initial processing on specification constructs, before visiting them.
void ResolveNamesVisitor::PreSpecificationConstruct(
const parser::SpecificationConstruct &spec) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::Statement<Indirection<parser::GenericStmt>> &y) {
CreateGeneric(std::get<parser::GenericSpec>(y.statement.value().t));
@@ -7093,21 +7095,21 @@ bool ResolveNamesVisitor::Pre(const parser::ImplicitStmt &x) {
}
void ResolveNamesVisitor::Post(const parser::PointerObject &x) {
- std::visit(common::visitors{
- [&](const parser::Name &x) { ResolveName(x); },
- [&](const parser::StructureComponent &x) {
- ResolveStructureComponent(x);
- },
- },
+ common::visit(common::visitors{
+ [&](const parser::Name &x) { ResolveName(x); },
+ [&](const parser::StructureComponent &x) {
+ ResolveStructureComponent(x);
+ },
+ },
x.u);
}
void ResolveNamesVisitor::Post(const parser::AllocateObject &x) {
- std::visit(common::visitors{
- [&](const parser::Name &x) { ResolveName(x); },
- [&](const parser::StructureComponent &x) {
- ResolveStructureComponent(x);
- },
- },
+ common::visit(common::visitors{
+ [&](const parser::Name &x) { ResolveName(x); },
+ [&](const parser::StructureComponent &x) {
+ ResolveStructureComponent(x);
+ },
+ },
x.u);
}
@@ -7240,7 +7242,7 @@ void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) {
Scope &scope{currScope()};
node.set_scope(scope);
AddSubpNames(node);
- std::visit(
+ common::visit(
[&](const auto *x) {
if (x) {
Walk(*x);
diff --git a/flang/lib/Semantics/rewrite-parse-tree.cpp b/flang/lib/Semantics/rewrite-parse-tree.cpp
index 071a668de7fd0..289a4e1d6e9ba 100644
--- a/flang/lib/Semantics/rewrite-parse-tree.cpp
+++ b/flang/lib/Semantics/rewrite-parse-tree.cpp
@@ -120,7 +120,7 @@ void RewriteMutator::Post(parser::IoUnit &x) {
// the I/O unit in situ to a FileUnitNumber so that automatic expression
// constraint checking will be applied.
auto source{var->GetSource()};
- auto expr{std::visit(
+ auto expr{common::visit(
[](auto &&indirection) {
return parser::Expr{std::move(indirection)};
},
@@ -159,7 +159,7 @@ void RewriteMutator::Post(parser::ReadStmt &x) {
const parser::Name &last{parser::GetLastName(*var)};
DeclTypeSpec *type{last.symbol ? last.symbol->GetType() : nullptr};
if (type && type->category() == DeclTypeSpec::Character) {
- x.format = std::visit(
+ x.format = common::visit(
[](auto &&indirection) {
return parser::Expr{std::move(indirection)};
},
diff --git a/flang/lib/Semantics/runtime-type-info.cpp b/flang/lib/Semantics/runtime-type-info.cpp
index 007567ff83f28..d24b844bd7b58 100644
--- a/flang/lib/Semantics/runtime-type-info.cpp
+++ b/flang/lib/Semantics/runtime-type-info.cpp
@@ -499,7 +499,7 @@ const Symbol *RuntimeTableBuilder::DescribeType(Scope &dtScope) {
for (const auto &pair : dtScope) {
const Symbol &symbol{*pair.second};
auto locationRestorer{common::ScopedSet(location_, symbol.name())};
- std::visit(
+ common::visit(
common::visitors{
[&](const TypeParamDetails &) {
// already handled above in declaration order
@@ -979,30 +979,30 @@ RuntimeTableBuilder::DescribeBindings(const Scope &dtScope, Scope &scope) {
void RuntimeTableBuilder::DescribeGeneric(const GenericDetails &generic,
std::map<int, evaluate::StructureConstructor> &specials) {
- std::visit(common::visitors{
- [&](const GenericKind::OtherKind &k) {
- if (k == GenericKind::OtherKind::Assignment) {
- for (auto ref : generic.specificProcs()) {
- DescribeSpecialProc(specials, *ref, true,
- false /*!final*/, std::nullopt);
- }
- }
- },
- [&](const GenericKind::DefinedIo &io) {
- switch (io) {
- case GenericKind::DefinedIo::ReadFormatted:
- case GenericKind::DefinedIo::ReadUnformatted:
- case GenericKind::DefinedIo::WriteFormatted:
- case GenericKind::DefinedIo::WriteUnformatted:
- for (auto ref : generic.specificProcs()) {
- DescribeSpecialProc(
- specials, *ref, false, false /*!final*/, io);
- }
- break;
- }
- },
- [](const auto &) {},
- },
+ common::visit(common::visitors{
+ [&](const GenericKind::OtherKind &k) {
+ if (k == GenericKind::OtherKind::Assignment) {
+ for (auto ref : generic.specificProcs()) {
+ DescribeSpecialProc(specials, *ref, true,
+ false /*!final*/, std::nullopt);
+ }
+ }
+ },
+ [&](const GenericKind::DefinedIo &io) {
+ switch (io) {
+ case GenericKind::DefinedIo::ReadFormatted:
+ case GenericKind::DefinedIo::ReadUnformatted:
+ case GenericKind::DefinedIo::WriteFormatted:
+ case GenericKind::DefinedIo::WriteUnformatted:
+ for (auto ref : generic.specificProcs()) {
+ DescribeSpecialProc(
+ specials, *ref, false, false /*!final*/, io);
+ }
+ break;
+ }
+ },
+ [](const auto &) {},
+ },
generic.kind().u);
}
diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index 8119e385bacfe..d3b1197420128 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -223,7 +223,7 @@ void GenericDetails::CopyFrom(const GenericDetails &from) {
// The name of the kind of details for this symbol.
// This is primarily for debugging.
std::string DetailsToString(const Details &details) {
- return std::visit(
+ return common::visit(
common::visitors{
[](const UnknownDetails &) { return "Unknown"; },
[](const MainProgramDetails &) { return "MainProgram"; },
@@ -261,7 +261,7 @@ bool Symbol::CanReplaceDetails(const Details &details) const {
if (has<UnknownDetails>()) {
return true; // can always replace UnknownDetails
} else {
- return std::visit(
+ return common::visit(
common::visitors{
[](const UseErrorDetails &) { return true; },
[&](const ObjectEntityDetails &) { return has<EntityDetails>(); },
@@ -291,14 +291,14 @@ void Symbol::ReplaceName(const SourceName &name) {
}
void Symbol::SetType(const DeclTypeSpec &type) {
- std::visit(common::visitors{
- [&](EntityDetails &x) { x.set_type(type); },
- [&](ObjectEntityDetails &x) { x.set_type(type); },
- [&](AssocEntityDetails &x) { x.set_type(type); },
- [&](ProcEntityDetails &x) { x.interface().set_type(type); },
- [&](TypeParamDetails &x) { x.set_type(type); },
- [](auto &) {},
- },
+ common::visit(common::visitors{
+ [&](EntityDetails &x) { x.set_type(type); },
+ [&](ObjectEntityDetails &x) { x.set_type(type); },
+ [&](AssocEntityDetails &x) { x.set_type(type); },
+ [&](ProcEntityDetails &x) { x.interface().set_type(type); },
+ [&](TypeParamDetails &x) { x.set_type(type); },
+ [](auto &) {},
+ },
details_);
}
@@ -306,7 +306,7 @@ template <typename T>
constexpr bool HasBindName{std::is_convertible_v<T, const WithBindName *>};
const std::string *Symbol::GetBindName() const {
- return std::visit(
+ return common::visit(
[&](auto &x) -> const std::string * {
if constexpr (HasBindName<decltype(&x)>) {
return x.bindName();
@@ -318,7 +318,7 @@ const std::string *Symbol::GetBindName() const {
}
void Symbol::SetBindName(std::string &&name) {
- std::visit(
+ common::visit(
[&](auto &x) {
if constexpr (HasBindName<decltype(&x)>) {
x.set_bindName(std::move(name));
@@ -330,7 +330,7 @@ void Symbol::SetBindName(std::string &&name) {
}
bool Symbol::IsFuncResult() const {
- return std::visit(
+ return common::visit(
common::visitors{[](const EntityDetails &x) { return x.isFuncResult(); },
[](const ObjectEntityDetails &x) { return x.isFuncResult(); },
[](const ProcEntityDetails &x) { return x.isFuncResult(); },
@@ -345,7 +345,7 @@ bool Symbol::IsObjectArray() const {
}
bool Symbol::IsSubprogram() const {
- return std::visit(
+ return common::visit(
common::visitors{
[](const SubprogramDetails &) { return true; },
[](const SubprogramNameDetails &) { return true; },
@@ -444,7 +444,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const GenericDetails &x) {
llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Details &details) {
os << DetailsToString(details);
- std::visit( //
+ common::visit( //
common::visitors{
[&](const UnknownDetails &) {},
[&](const MainProgramDetails &) {},
@@ -667,7 +667,7 @@ bool GenericKind::IsOperator() const {
}
std::string GenericKind::ToString() const {
- return std::visit(
+ return common::visit(
common::visitors {
[](const OtherKind &x) { return EnumToString(x); },
[](const DefinedIo &x) { return AsFortran(x).ToString(); },
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index a1b4ea9ec0e2c..0b345a66a4788 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -428,7 +428,7 @@ const evaluate::Assignment *GetAssignment(
}
const Symbol *FindInterface(const Symbol &symbol) {
- return std::visit(
+ return common::visit(
common::visitors{
[](const ProcEntityDetails &details) {
return details.interface().symbol();
@@ -440,7 +440,7 @@ const Symbol *FindInterface(const Symbol &symbol) {
}
const Symbol *FindSubprogram(const Symbol &symbol) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const ProcEntityDetails &details) -> const Symbol * {
if (const Symbol * interface{details.interface().symbol()}) {
@@ -932,7 +932,7 @@ class ImageControlStmtHelper {
return false;
}
bool operator()(const parser::Statement<parser::ActionStmt> &stmt) {
- return std::visit(*this, stmt.statement.u);
+ return common::visit(*this, stmt.statement.u);
}
private:
@@ -943,14 +943,14 @@ class ImageControlStmtHelper {
};
bool IsImageControlStmt(const parser::ExecutableConstruct &construct) {
- return std::visit(ImageControlStmtHelper{}, construct.u);
+ return common::visit(ImageControlStmtHelper{}, construct.u);
}
std::optional<parser::MessageFixedText> GetImageControlStmtCoarrayMsg(
const parser::ExecutableConstruct &construct) {
if (const auto *actionStmt{
std::get_if<parser::Statement<parser::ActionStmt>>(&construct.u)}) {
- return std::visit(
+ return common::visit(
common::visitors{
[](const common::Indirection<parser::AllocateStmt> &)
-> std::optional<parser::MessageFixedText> {
@@ -978,7 +978,7 @@ std::optional<parser::MessageFixedText> GetImageControlStmtCoarrayMsg(
parser::CharBlock GetImageControlStmtLocation(
const parser::ExecutableConstruct &executableConstruct) {
- return std::visit(
+ return common::visit(
common::visitors{
[](const common::Indirection<parser::ChangeTeamConstruct>
&construct) {
@@ -1447,7 +1447,7 @@ bool InCommonBlock(const Symbol &symbol) {
const std::optional<parser::Name> &MaybeGetNodeName(
const ConstructNode &construct) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const parser::BlockConstruct *blockConstruct)
-> const std::optional<parser::Name> & {
diff --git a/flang/runtime/io-stmt.cpp b/flang/runtime/io-stmt.cpp
index ac2a7e0a11ed2..f50d332e108f4 100644
--- a/flang/runtime/io-stmt.cpp
+++ b/flang/runtime/io-stmt.cpp
@@ -455,26 +455,26 @@ int ExternalFormattedIoStatementState<DIR, CHAR>::EndIoStatement() {
}
std::optional<DataEdit> IoStatementState::GetNextDataEdit(int n) {
- return std::visit(
+ return common::visit(
[&](auto &x) { return x.get().GetNextDataEdit(*this, n); }, u_);
}
bool IoStatementState::Emit(
const char *data, std::size_t n, std::size_t elementBytes) {
- return std::visit(
+ return common::visit(
[=](auto &x) { return x.get().Emit(data, n, elementBytes); }, u_);
}
bool IoStatementState::Emit(const char *data, std::size_t n) {
- return std::visit([=](auto &x) { return x.get().Emit(data, n); }, u_);
+ return common::visit([=](auto &x) { return x.get().Emit(data, n); }, u_);
}
bool IoStatementState::Emit(const char16_t *data, std::size_t chars) {
- return std::visit([=](auto &x) { return x.get().Emit(data, chars); }, u_);
+ return common::visit([=](auto &x) { return x.get().Emit(data, chars); }, u_);
}
bool IoStatementState::Emit(const char32_t *data, std::size_t chars) {
- return std::visit([=](auto &x) { return x.get().Emit(data, chars); }, u_);
+ return common::visit([=](auto &x) { return x.get().Emit(data, chars); }, u_);
}
template <typename CHAR>
@@ -503,55 +503,57 @@ bool IoStatementState::EmitEncoded(const CHAR *data0, std::size_t chars) {
bool IoStatementState::Receive(
char *data, std::size_t n, std::size_t elementBytes) {
- return std::visit(
+ return common::visit(
[=](auto &x) { return x.get().Receive(data, n, elementBytes); }, u_);
}
std::size_t IoStatementState::GetNextInputBytes(const char *&p) {
- return std::visit([&](auto &x) { return x.get().GetNextInputBytes(p); }, u_);
+ return common::visit(
+ [&](auto &x) { return x.get().GetNextInputBytes(p); }, u_);
}
bool IoStatementState::AdvanceRecord(int n) {
- return std::visit([=](auto &x) { return x.get().AdvanceRecord(n); }, u_);
+ return common::visit([=](auto &x) { return x.get().AdvanceRecord(n); }, u_);
}
void IoStatementState::BackspaceRecord() {
- std::visit([](auto &x) { x.get().BackspaceRecord(); }, u_);
+ common::visit([](auto &x) { x.get().BackspaceRecord(); }, u_);
}
void IoStatementState::HandleRelativePosition(std::int64_t n) {
- std::visit([=](auto &x) { x.get().HandleRelativePosition(n); }, u_);
+ common::visit([=](auto &x) { x.get().HandleRelativePosition(n); }, u_);
}
void IoStatementState::HandleAbsolutePosition(std::int64_t n) {
- std::visit([=](auto &x) { x.get().HandleAbsolutePosition(n); }, u_);
+ common::visit([=](auto &x) { x.get().HandleAbsolutePosition(n); }, u_);
}
void IoStatementState::CompleteOperation() {
- std::visit([](auto &x) { x.get().CompleteOperation(); }, u_);
+ common::visit([](auto &x) { x.get().CompleteOperation(); }, u_);
}
int IoStatementState::EndIoStatement() {
- return std::visit([](auto &x) { return x.get().EndIoStatement(); }, u_);
+ return common::visit([](auto &x) { return x.get().EndIoStatement(); }, u_);
}
ConnectionState &IoStatementState::GetConnectionState() {
- return std::visit(
+ return common::visit(
[](auto &x) -> ConnectionState & { return x.get().GetConnectionState(); },
u_);
}
MutableModes &IoStatementState::mutableModes() {
- return std::visit(
+ return common::visit(
[](auto &x) -> MutableModes & { return x.get().mutableModes(); }, u_);
}
bool IoStatementState::BeginReadingRecord() {
- return std::visit([](auto &x) { return x.get().BeginReadingRecord(); }, u_);
+ return common::visit(
+ [](auto &x) { return x.get().BeginReadingRecord(); }, u_);
}
IoErrorHandler &IoStatementState::GetIoErrorHandler() const {
- return std::visit(
+ return common::visit(
[](auto &x) -> IoErrorHandler & {
return static_cast<IoErrorHandler &>(x.get());
},
@@ -559,7 +561,8 @@ IoErrorHandler &IoStatementState::GetIoErrorHandler() const {
}
ExternalFileUnit *IoStatementState::GetExternalFileUnit() const {
- return std::visit([](auto &x) { return x.get().GetExternalFileUnit(); }, u_);
+ return common::visit(
+ [](auto &x) { return x.get().GetExternalFileUnit(); }, u_);
}
std::optional<char32_t> IoStatementState::GetCurrentChar(
@@ -587,7 +590,7 @@ std::optional<char32_t> IoStatementState::GetCurrentChar(
}
bool IoStatementState::EmitRepeated(char ch, std::size_t n) {
- return std::visit(
+ return common::visit(
[=](auto &x) {
for (std::size_t j{0}; j < n; ++j) {
if (!x.get().Emit(&ch, 1)) {
@@ -683,22 +686,24 @@ bool IoStatementState::CheckForEndOfRecord() {
bool IoStatementState::Inquire(
InquiryKeywordHash inquiry, char *out, std::size_t chars) {
- return std::visit(
+ return common::visit(
[&](auto &x) { return x.get().Inquire(inquiry, out, chars); }, u_);
}
bool IoStatementState::Inquire(InquiryKeywordHash inquiry, bool &out) {
- return std::visit([&](auto &x) { return x.get().Inquire(inquiry, out); }, u_);
+ return common::visit(
+ [&](auto &x) { return x.get().Inquire(inquiry, out); }, u_);
}
bool IoStatementState::Inquire(
InquiryKeywordHash inquiry, std::int64_t id, bool &out) {
- return std::visit(
+ return common::visit(
[&](auto &x) { return x.get().Inquire(inquiry, id, out); }, u_);
}
bool IoStatementState::Inquire(InquiryKeywordHash inquiry, std::int64_t &n) {
- return std::visit([&](auto &x) { return x.get().Inquire(inquiry, n); }, u_);
+ return common::visit(
+ [&](auto &x) { return x.get().Inquire(inquiry, n); }, u_);
}
void IoStatementState::GotChar(int n) {
diff --git a/flang/runtime/io-stmt.h b/flang/runtime/io-stmt.h
index 41bcfa3bb217d..b076d06e14ab9 100644
--- a/flang/runtime/io-stmt.h
+++ b/flang/runtime/io-stmt.h
@@ -16,6 +16,7 @@
#include "format.h"
#include "internal-unit.h"
#include "io-error.h"
+#include "flang/Common/visit.h"
#include "flang/Runtime/descriptor.h"
#include "flang/Runtime/io-api.h"
#include <functional>
@@ -113,7 +114,7 @@ class IoStatementState {
// N.B.: this also works with base classes
template <typename A> A *get_if() const {
- return std::visit(
+ return common::visit(
[](auto &x) -> A * {
if constexpr (std::is_convertible_v<decltype(x.get()), A &>) {
return &x.get();
More information about the flang-commits
mailing list