[llvm-branch-commits] [flang] [flang] Add traits to more AST nodes (PR #175578)
Krzysztof Parzyszek via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Jan 12 08:22:44 PST 2026
https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/175578
Follow-up to PR175211.
There are still a few AST nodes that don't have any of the standard traits (Wrapper/Tuple/etc). Because of that they require special handling in the parse tree visitor.
Convert a subset of these nodes to the typical format, and remove the special cases from the parse tree visitor.
The members of these nodes were frequently used, so instead of extracting them by hand each time use helper member functions to access them.
>From a3f6a10e94f29c96390b0be7c37ef74e1668bb5b Mon Sep 17 00:00:00 2001
From: Krzysztof Parzyszek <Krzysztof.Parzyszek at amd.com>
Date: Thu, 8 Jan 2026 09:05:10 -0600
Subject: [PATCH] [flang] Add traits to more AST nodes
Follow-up to PR175211.
There are still a few AST nodes that don't have any of the standard
traits (Wrapper/Tuple/etc). Because of that they require special
handling in the parse tree visitor.
Convert a subset of these nodes to the typical format, and remove the
special cases from the parse tree visitor.
The members of these nodes were frequently used, so instead of extracting
them by hand each time use helper member functions to access them.
---
.../include/flang/Parser/parse-tree-visitor.h | 65 ----------------
flang/include/flang/Parser/parse-tree.h | 45 +++++------
flang/lib/Lower/Bridge.cpp | 14 ++--
flang/lib/Lower/IO.cpp | 10 +--
flang/lib/Lower/OpenACC.cpp | 16 ++--
flang/lib/Lower/OpenMP/OpenMP.cpp | 10 +--
flang/lib/Lower/OpenMP/Utils.cpp | 22 +++---
flang/lib/Lower/PFTBuilder.cpp | 2 +-
flang/lib/Parser/parse-tree.cpp | 12 ++-
flang/lib/Parser/tools.cpp | 20 +++--
flang/lib/Parser/unparse.cpp | 14 ++--
flang/lib/Semantics/check-cuda.cpp | 8 +-
flang/lib/Semantics/check-data.cpp | 4 +-
flang/lib/Semantics/check-deallocate.cpp | 6 +-
flang/lib/Semantics/check-do-forall.cpp | 20 ++---
flang/lib/Semantics/check-nullify.cpp | 2 +-
flang/lib/Semantics/check-omp-loop.cpp | 2 +-
flang/lib/Semantics/check-omp-structure.cpp | 18 ++---
flang/lib/Semantics/data-to-inits.cpp | 14 ++--
flang/lib/Semantics/expression.cpp | 78 ++++++++++---------
flang/lib/Semantics/resolve-directives.cpp | 18 ++---
flang/lib/Semantics/resolve-names-utils.cpp | 4 +-
flang/lib/Semantics/resolve-names.cpp | 39 +++++-----
23 files changed, 194 insertions(+), 249 deletions(-)
diff --git a/flang/include/flang/Parser/parse-tree-visitor.h b/flang/include/flang/Parser/parse-tree-visitor.h
index 191e74ee89f1c..5aff5152a3793 100644
--- a/flang/include/flang/Parser/parse-tree-visitor.h
+++ b/flang/include/flang/Parser/parse-tree-visitor.h
@@ -314,56 +314,6 @@ struct ParseTreeVisitorLookupScope {
}
}
- template <typename V> static void Walk(const ArrayElement &x, V &visitor) {
- if (visitor.Pre(x)) {
- Walk(x.base, visitor);
- Walk(x.subscripts, visitor);
- visitor.Post(x);
- }
- }
- template <typename M> static void Walk(ArrayElement &x, M &mutator) {
- if (mutator.Pre(x)) {
- Walk(x.base, mutator);
- Walk(x.subscripts, mutator);
- mutator.Post(x);
- }
- }
- template <typename V>
- static void Walk(const CoindexedNamedObject &x, V &visitor) {
- if (visitor.Pre(x)) {
- Walk(x.base, visitor);
- Walk(x.imageSelector, visitor);
- visitor.Post(x);
- }
- }
- template <typename M> static void Walk(CoindexedNamedObject &x, M &mutator) {
- if (mutator.Pre(x)) {
- Walk(x.base, mutator);
- Walk(x.imageSelector, mutator);
- mutator.Post(x);
- }
- }
- template <typename A, typename B, typename V>
- static void Walk(const LoopBounds<A, B> &x, V &visitor) {
- if (visitor.Pre(x)) {
- Walk(x.name, visitor);
- Walk(x.lower, visitor);
- Walk(x.upper, visitor);
- Walk(x.step, visitor);
- visitor.Post(x);
- }
- }
- template <typename A, typename B, typename M>
- static void Walk(LoopBounds<A, B> &x, M &mutator) {
- if (mutator.Pre(x)) {
- Walk(x.name, mutator);
- Walk(x.lower, mutator);
- Walk(x.upper, mutator);
- Walk(x.step, mutator);
- mutator.Post(x);
- }
- }
-
// Expr traversal uses iteration rather than recursion to avoid
// blowing out the stack on very deep expression parse trees.
// It replaces implementations that looked like:
@@ -451,21 +401,6 @@ struct ParseTreeVisitorLookupScope {
mutator.Post(x);
}
}
- template <typename V>
- static void Walk(const StructureComponent &x, V &visitor) {
- if (visitor.Pre(x)) {
- Walk(x.base, visitor);
- Walk(x.component, visitor);
- visitor.Post(x);
- }
- }
- template <typename M> static void Walk(StructureComponent &x, M &mutator) {
- if (mutator.Pre(x)) {
- Walk(x.base, mutator);
- Walk(x.component, mutator);
- mutator.Post(x);
- }
- }
template <typename V> static void Walk(const UseStmt &x, V &visitor) {
if (visitor.Pre(x)) {
Walk(x.nature, visitor);
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index c03823b60f0de..6c1aace66275f 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -1256,15 +1256,13 @@ WRAPPER_CLASS(ArrayConstructor, AcSpec);
using DoVariable = Scalar<Integer<Name>>;
template <typename VAR, typename BOUND> struct LoopBounds {
- LoopBounds(LoopBounds &&that) = default;
- LoopBounds(
- VAR &&name, BOUND &&lower, BOUND &&upper, std::optional<BOUND> &&step)
- : name{std::move(name)}, lower{std::move(lower)}, upper{std::move(upper)},
- step{std::move(step)} {}
- LoopBounds &operator=(LoopBounds &&) = default;
- VAR name;
- BOUND lower, upper;
- std::optional<BOUND> step;
+ TUPLE_CLASS_BOILERPLATE(LoopBounds);
+ std::tuple<VAR, BOUND, BOUND, std::optional<BOUND>> t;
+
+ const VAR &Name() const { return std::get<0>(t); }
+ const BOUND &Lower() const { return std::get<1>(t); }
+ const BOUND &Upper() const { return std::get<2>(t); }
+ const std::optional<BOUND> &Step() const { return std::get<3>(t); }
};
using ScalarName = Scalar<Name>;
@@ -1858,11 +1856,11 @@ using ScalarIntVariable = Scalar<Integer<Variable>>;
// R913 structure-component -> data-ref
struct StructureComponent {
- BOILERPLATE(StructureComponent);
- StructureComponent(DataRef &&dr, Name &&n)
- : base{std::move(dr)}, component(std::move(n)) {}
- DataRef base;
- Name component;
+ TUPLE_CLASS_BOILERPLATE(StructureComponent);
+ std::tuple<DataRef, Name> t;
+
+ const DataRef &Base() const { return std::get<DataRef>(t); }
+ const Name &Component() const { return std::get<Name>(t); }
};
// R1039 proc-component-ref -> scalar-variable % procedure-component-name
@@ -1873,23 +1871,22 @@ struct ProcComponentRef {
// R914 coindexed-named-object -> data-ref
struct CoindexedNamedObject {
- BOILERPLATE(CoindexedNamedObject);
- CoindexedNamedObject(DataRef &&dr, ImageSelector &&is)
- : base{std::move(dr)}, imageSelector{std::move(is)} {}
- DataRef base;
- ImageSelector imageSelector;
+ TUPLE_CLASS_BOILERPLATE(CoindexedNamedObject);
+ std::tuple<DataRef, ImageSelector> t;
};
// R917 array-element -> data-ref
struct ArrayElement {
- BOILERPLATE(ArrayElement);
- ArrayElement(DataRef &&dr, std::list<SectionSubscript> &&ss)
- : base{std::move(dr)}, subscripts(std::move(ss)) {}
+ TUPLE_CLASS_BOILERPLATE(ArrayElement);
Substring ConvertToSubstring();
StructureConstructor ConvertToStructureConstructor(
const semantics::DerivedTypeSpec &);
- DataRef base;
- std::list<SectionSubscript> subscripts;
+ std::tuple<DataRef, std::list<SectionSubscript>> t;
+
+ const DataRef &Base() const { return std::get<DataRef>(t); }
+ const std::list<SectionSubscript> &Subscripts() const {
+ return std::get<std::list<SectionSubscript>>(t);
+ }
};
// R933 allocate-object -> variable-name | structure-component
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 609050511f6c9..656940986809d 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -2491,8 +2491,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
&loopControl->u)) {
// Non-concurrent increment loop.
IncrementLoopInfo &info = incrementLoopNestInfo.emplace_back(
- *bounds->name.thing.symbol, bounds->lower, bounds->upper,
- bounds->step);
+ *bounds->Name().thing.symbol, bounds->Lower(), bounds->Upper(),
+ bounds->Step());
if (unstructuredContext) {
maybeStartBlock(preheaderBlock);
info.hasRealControl = info.loopVariableSym->GetType()->IsNumeric(
@@ -3842,22 +3842,22 @@ class FirConverter : public Fortran::lower::AbstractConverter {
assert(bounds && "Expected bounds on the loop construct");
Fortran::semantics::Symbol &ivSym =
- bounds->name.thing.symbol->GetUltimate();
+ bounds->Name().thing.symbol->GetUltimate();
ivValues.push_back(getSymbolAddress(ivSym));
lbs.push_back(builder->createConvert(
crtLoc, idxTy,
fir::getBase(genExprValue(
- *Fortran::semantics::GetExpr(bounds->lower), stmtCtx))));
+ *Fortran::semantics::GetExpr(bounds->Lower()), stmtCtx))));
ubs.push_back(builder->createConvert(
crtLoc, idxTy,
fir::getBase(genExprValue(
- *Fortran::semantics::GetExpr(bounds->upper), stmtCtx))));
- if (bounds->step)
+ *Fortran::semantics::GetExpr(bounds->Upper()), stmtCtx))));
+ if (auto &step = bounds->Step())
steps.push_back(builder->createConvert(
crtLoc, idxTy,
fir::getBase(genExprValue(
- *Fortran::semantics::GetExpr(bounds->step), stmtCtx))));
+ *Fortran::semantics::GetExpr(step), stmtCtx))));
else // If `step` is not present, assume it is `1`.
steps.push_back(builder->createIntegerConstant(loc, idxTy, 1));
diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp
index c3f9c1a882423..de2afb70636d5 100644
--- a/flang/lib/Lower/IO.cpp
+++ b/flang/lib/Lower/IO.cpp
@@ -951,7 +951,7 @@ static void genIoLoop(Fortran::lower::AbstractConverter &converter,
const auto &itemList = std::get<0>(ioImpliedDo.t);
const auto &control = std::get<1>(ioImpliedDo.t);
const auto &loopSym =
- *Fortran::parser::UnwrapRef<Fortran::parser::Name>(control.name).symbol;
+ *Fortran::parser::UnwrapRef<Fortran::parser::Name>(control.Name()).symbol;
mlir::Value loopVar = fir::getBase(converter.genExprAddr(
Fortran::evaluate::AsGenericExpr(loopSym).value(), stmtCtx));
auto genControlValue = [&](const Fortran::parser::ScalarIntExpr &expr) {
@@ -959,11 +959,11 @@ static void genIoLoop(Fortran::lower::AbstractConverter &converter,
converter.genExprValue(*Fortran::semantics::GetExpr(expr), stmtCtx));
return builder.createConvert(loc, builder.getIndexType(), v);
};
- mlir::Value lowerValue = genControlValue(control.lower);
- mlir::Value upperValue = genControlValue(control.upper);
+ mlir::Value lowerValue = genControlValue(control.Lower());
+ mlir::Value upperValue = genControlValue(control.Upper());
mlir::Value stepValue =
- control.step.has_value()
- ? genControlValue(*control.step)
+ control.Step().has_value()
+ ? genControlValue(*control.Step())
: mlir::arith::ConstantIndexOp::create(builder, loc, 1);
auto genItemList = [&](const D &ioImpliedDo) {
if constexpr (std::is_same_v<D, Fortran::parser::InputImpliedDo>)
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 52fee7baf9de1..64e39b610aa6e 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -305,13 +305,13 @@ getSymbolFromAccObject(const Fortran::parser::AccObject &accObject) {
Fortran::parser::Unwrap<Fortran::parser::ArrayElement>(
*designator)) {
const Fortran::parser::Name &name =
- Fortran::parser::GetLastName(arrayElement->base);
+ Fortran::parser::GetLastName(arrayElement->Base());
return *name.symbol;
}
if (const auto *component =
Fortran::parser::Unwrap<Fortran::parser::StructureComponent>(
*designator)) {
- return *component->component.symbol;
+ return *component->Component().symbol;
}
} else if (const auto *name =
std::get_if<Fortran::parser::Name>(&accObject.u)) {
@@ -2173,18 +2173,18 @@ static void processDoLoopBounds(
mlir::Location loc) {
locs.push_back(loc);
lowerbounds.push_back(fir::getBase(converter.genExprValue(
- *Fortran::semantics::GetExpr(bounds.lower), stmtCtx)));
+ *Fortran::semantics::GetExpr(bounds.Lower()), stmtCtx)));
upperbounds.push_back(fir::getBase(converter.genExprValue(
- *Fortran::semantics::GetExpr(bounds.upper), stmtCtx)));
- if (bounds.step)
+ *Fortran::semantics::GetExpr(bounds.Upper()), stmtCtx)));
+ if (auto &step = bounds.Step())
steps.push_back(fir::getBase(converter.genExprValue(
- *Fortran::semantics::GetExpr(bounds.step), stmtCtx)));
+ *Fortran::semantics::GetExpr(step), stmtCtx)));
else // If `step` is not present, assume it is `1`.
steps.push_back(builder.createIntegerConstant(
currentLocation, upperbounds[upperbounds.size() - 1].getType(),
1));
Fortran::semantics::Symbol &ivSym =
- bounds.name.thing.symbol->GetUltimate();
+ bounds.Name().thing.symbol->GetUltimate();
privatizeIv(converter, ivSym, currentLocation, ivTypes, ivLocs,
privateOperands, ivPrivate);
@@ -2355,7 +2355,7 @@ static void privatizeInductionVariables(
mlir::Location loc) {
locs.push_back(loc);
Fortran::semantics::Symbol &ivSym =
- bounds.name.thing.symbol->GetUltimate();
+ bounds.Name().thing.symbol->GetUltimate();
privatizeIv(converter, ivSym, currentLocation, ivTypes,
ivLocs, privateOperands, ivPrivate);
});
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 989e370870f33..1c84d8a38d6b6 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2090,13 +2090,13 @@ static void genCanonicalLoopNest(
assert(bounds && "Expected bounds for canonical loop");
lower::StatementContext stmtCtx;
mlir::Value loopLBVar = fir::getBase(
- converter.genExprValue(*semantics::GetExpr(bounds->lower), stmtCtx));
+ converter.genExprValue(*semantics::GetExpr(bounds->Lower()), stmtCtx));
mlir::Value loopUBVar = fir::getBase(
- converter.genExprValue(*semantics::GetExpr(bounds->upper), stmtCtx));
+ converter.genExprValue(*semantics::GetExpr(bounds->Upper()), stmtCtx));
mlir::Value loopStepVar = [&]() {
- if (bounds->step) {
+ if (auto &step = bounds->Step()) {
return fir::getBase(
- converter.genExprValue(*semantics::GetExpr(bounds->step), stmtCtx));
+ converter.genExprValue(*semantics::GetExpr(step), stmtCtx));
}
// If `step` is not present, assume it is `1`.
@@ -2105,7 +2105,7 @@ static void genCanonicalLoopNest(
}();
// Get the integer kind for the loop variable and cast the loop bounds
- size_t loopVarTypeSize = bounds->name.thing.symbol->GetUltimate().size();
+ size_t loopVarTypeSize = bounds->Name().thing.symbol->GetUltimate().size();
mlir::Type loopVarType = getLoopVarType(converter, loopVarTypeSize);
loopVarTypes.push_back(loopVarType);
loopLBVar = firOpBuilder.createConvert(loc, loopVarType, loopLBVar);
diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp
index a818d635668de..dce8580856664 100644
--- a/flang/lib/Lower/OpenMP/Utils.cpp
+++ b/flang/lib/Lower/OpenMP/Utils.cpp
@@ -31,6 +31,7 @@
#include <flang/Semantics/tools.h>
#include <flang/Semantics/type.h>
#include <flang/Utils/OpenMP.h>
+#include <llvm/ADT/STLExtras.h>
#include <llvm/ADT/SmallPtrSet.h>
#include <llvm/ADT/StringRef.h>
#include <llvm/Support/CommandLine.h>
@@ -255,9 +256,10 @@ getIterationVariableSymbol(const lower::pft::Evaluation &eval) {
if (const auto &maybeCtrl = doLoop.GetLoopControl()) {
using LoopControl = parser::LoopControl;
if (auto *bounds = std::get_if<LoopControl::Bounds>(&maybeCtrl->u)) {
- static_assert(std::is_same_v<decltype(bounds->name),
- parser::Scalar<parser::Name>>);
- return bounds->name.thing.symbol;
+ using NameType = llvm::remove_cvref_t<decltype(bounds->Name())>;
+ static_assert(
+ std::is_same_v<NameType, parser::Scalar<parser::Name>>);
+ return bounds->Name().thing.symbol;
}
}
return static_cast<semantics::Symbol *>(nullptr);
@@ -894,19 +896,19 @@ void collectLoopRelatedInfo(
assert(bounds && "Expected bounds for worksharing do loop");
lower::StatementContext stmtCtx;
result.loopLowerBounds.push_back(fir::getBase(
- converter.genExprValue(*semantics::GetExpr(bounds->lower), stmtCtx)));
+ converter.genExprValue(*semantics::GetExpr(bounds->Lower()), stmtCtx)));
result.loopUpperBounds.push_back(fir::getBase(
- converter.genExprValue(*semantics::GetExpr(bounds->upper), stmtCtx)));
- if (bounds->step) {
+ converter.genExprValue(*semantics::GetExpr(bounds->Upper()), stmtCtx)));
+ if (auto &step = bounds->Step()) {
result.loopSteps.push_back(fir::getBase(
- converter.genExprValue(*semantics::GetExpr(bounds->step), stmtCtx)));
+ converter.genExprValue(*semantics::GetExpr(step), stmtCtx)));
} else { // If `step` is not present, assume it as `1`.
result.loopSteps.push_back(firOpBuilder.createIntegerConstant(
currentLocation, firOpBuilder.getIntegerType(32), 1));
}
- iv.push_back(bounds->name.thing.symbol);
- loopVarTypeSize = std::max(loopVarTypeSize,
- bounds->name.thing.symbol->GetUltimate().size());
+ iv.push_back(bounds->Name().thing.symbol);
+ loopVarTypeSize = std::max(
+ loopVarTypeSize, bounds->Name().thing.symbol->GetUltimate().size());
if (--collapseValue)
doConstructEval = getNestedDoConstruct(*doConstructEval);
} while (collapseValue > 0);
diff --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp
index 1a7fb41f3273c..308db726f073c 100644
--- a/flang/lib/Lower/PFTBuilder.cpp
+++ b/flang/lib/Lower/PFTBuilder.cpp
@@ -1055,7 +1055,7 @@ class PFTBuilder {
eval.controlSuccessor = &evaluationList.back();
if (const auto *bounds =
std::get_if<parser::LoopControl::Bounds>(&loopControl->u)) {
- if (bounds->name.thing.symbol->GetType()->IsNumeric(
+ if (bounds->Name().thing.symbol->GetType()->IsNumeric(
common::TypeCategory::Real))
eval.isUnstructured = true; // real-valued loop control
} else if (std::get_if<parser::ScalarLogicalExpr>(
diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp
index e0c668ddc328b..afe28182f8627 100644
--- a/flang/lib/Parser/parse-tree.cpp
+++ b/flang/lib/Parser/parse-tree.cpp
@@ -102,8 +102,9 @@ static Designator MakeArrayElementRef(
const Name &name, std::list<Expr> &&subscripts) {
ArrayElement arrayElement{DataRef{Name{name}}, std::list<SectionSubscript>{}};
for (Expr &expr : subscripts) {
- arrayElement.subscripts.push_back(
- SectionSubscript{Integer{common::Indirection{std::move(expr)}}});
+ std::get<std::list<SectionSubscript>>(arrayElement.t)
+ .push_back(
+ SectionSubscript{Integer{common::Indirection{std::move(expr)}}});
}
return Designator{DataRef{common::Indirection{std::move(arrayElement)}}};
}
@@ -113,8 +114,9 @@ static Designator MakeArrayElementRef(
ArrayElement arrayElement{DataRef{common::Indirection{std::move(sc)}},
std::list<SectionSubscript>{}};
for (Expr &expr : subscripts) {
- arrayElement.subscripts.push_back(
- SectionSubscript{Integer{common::Indirection{std::move(expr)}}});
+ std::get<std::list<SectionSubscript>>(arrayElement.t)
+ .push_back(
+ SectionSubscript{Integer{common::Indirection{std::move(expr)}}});
}
return Designator{DataRef{common::Indirection{std::move(arrayElement)}}};
}
@@ -186,6 +188,7 @@ StructureConstructor FunctionReference::ConvertToStructureConstructor(
StructureConstructor ArrayElement::ConvertToStructureConstructor(
const semantics::DerivedTypeSpec &derived) {
+ auto &[base, subscripts]{t};
Name name{std::get<parser::Name>(base.u)};
std::list<ComponentSpec> components;
for (auto &subscript : subscripts) {
@@ -198,6 +201,7 @@ StructureConstructor ArrayElement::ConvertToStructureConstructor(
}
Substring ArrayElement::ConvertToSubstring() {
+ auto &[base, subscripts]{t};
auto iter{subscripts.begin()};
CHECK(iter != subscripts.end());
auto &triplet{std::get<SubscriptTriplet>(iter->u)};
diff --git a/flang/lib/Parser/tools.cpp b/flang/lib/Parser/tools.cpp
index ed6d194c17dc3..ff0538ae565b2 100644
--- a/flang/lib/Parser/tools.cpp
+++ b/flang/lib/Parser/tools.cpp
@@ -13,7 +13,7 @@ namespace Fortran::parser {
const Name &GetLastName(const Name &x) { return x; }
const Name &GetLastName(const StructureComponent &x) {
- return GetLastName(x.component);
+ return GetLastName(x.Component());
}
const Name &GetLastName(const DataRef &x) {
@@ -23,10 +23,12 @@ const Name &GetLastName(const DataRef &x) {
[](const common::Indirection<StructureComponent> &sc)
-> const Name & { return GetLastName(sc.value()); },
[](const common::Indirection<ArrayElement> &sc) -> const Name & {
- return GetLastName(sc.value().base);
+ return GetLastName(sc.value().Base());
},
[](const common::Indirection<CoindexedNamedObject> &ci)
- -> const Name & { return GetLastName(ci.value().base); },
+ -> const Name & {
+ return GetLastName(std::get<DataRef>(ci.value().t));
+ },
},
x.u);
}
@@ -71,7 +73,7 @@ const Name &GetLastName(const AllocateObject &x) {
const Name &GetFirstName(const Name &x) { return x; }
const Name &GetFirstName(const StructureComponent &x) {
- return GetFirstName(x.base);
+ return GetFirstName(x.Base());
}
const Name &GetFirstName(const DataRef &x) {
@@ -81,10 +83,12 @@ const Name &GetFirstName(const DataRef &x) {
[](const common::Indirection<StructureComponent> &sc)
-> const Name & { return GetFirstName(sc.value()); },
[](const common::Indirection<ArrayElement> &sc) -> const Name & {
- return GetFirstName(sc.value().base);
+ return GetFirstName(sc.value().Base());
},
[](const common::Indirection<CoindexedNamedObject> &ci)
- -> const Name & { return GetFirstName(ci.value().base); },
+ -> const Name & {
+ return GetFirstName(std::get<DataRef>(ci.value().t));
+ },
},
x.u);
}
@@ -134,7 +138,7 @@ const CoindexedNamedObject *GetCoindexedNamedObject(const DataRef &base) {
[](const common::Indirection<CoindexedNamedObject> &x)
-> const CoindexedNamedObject * { return &x.value(); },
[](const auto &x) -> const CoindexedNamedObject * {
- return GetCoindexedNamedObject(x.value().base);
+ return GetCoindexedNamedObject(x.value().Base());
},
},
base.u);
@@ -168,7 +172,7 @@ const CoindexedNamedObject *GetCoindexedNamedObject(
return common::visit(
common::visitors{
[](const StructureComponent &x) -> const CoindexedNamedObject * {
- return GetCoindexedNamedObject(x.base);
+ return GetCoindexedNamedObject(x.Base());
},
[](const auto &) -> const CoindexedNamedObject * { return nullptr; },
},
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 0465b67aed08d..fb7a7ec8517f4 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -440,8 +440,8 @@ class UnparseVisitor {
Walk(std::get<std::list<AcValue>>(x.t), ", ");
}
template <typename A, typename B> void Unparse(const LoopBounds<A, B> &x) {
- Walk(x.name), Put('='), Walk(x.lower), Put(','), Walk(x.upper);
- Walk(",", x.step);
+ Walk(x.Name()), Put('='), Walk(x.Lower()), Put(','), Walk(x.Upper());
+ Walk(",", x.Step());
}
void Unparse(const AcImpliedDo &x) { // R774
Put('('), Walk(std::get<std::list<AcValue>>(x.t), ", ");
@@ -798,18 +798,18 @@ class UnparseVisitor {
Walk(imageSelector);
}
void Unparse(const StructureComponent &x) { // R913
- Walk(x.base);
- if (structureComponents_.find(x.component.source) !=
+ Walk(x.Base());
+ if (structureComponents_.find(x.Component().source) !=
structureComponents_.end()) {
Put('.');
} else {
Put('%');
}
- Walk(x.component);
+ Walk(x.Component());
}
void Unparse(const ArrayElement &x) { // R917
- Walk(x.base);
- Put('('), Walk(x.subscripts, ","), Put(')');
+ Walk(x.Base());
+ Put('('), Walk(x.Subscripts(), ","), Put(')');
}
void Unparse(const SubscriptTriplet &x) { // R921
Walk(std::get<0>(x.t)), Put(':'), Walk(std::get<1>(x.t));
diff --git a/flang/lib/Semantics/check-cuda.cpp b/flang/lib/Semantics/check-cuda.cpp
index caa9bdd28f1f4..13c523da13c25 100644
--- a/flang/lib/Semantics/check-cuda.cpp
+++ b/flang/lib/Semantics/check-cuda.cpp
@@ -514,10 +514,10 @@ template <bool IsCUFKernelDo> class DeviceContextChecker {
Check(uS.statement, uS.source);
}
void Check(const parser::LoopControl::Bounds &bounds) {
- Check(bounds.lower);
- Check(bounds.upper);
- if (bounds.step) {
- Check(*bounds.step);
+ Check(bounds.Lower());
+ Check(bounds.Upper());
+ if (auto &step{bounds.Step()}) {
+ Check(*step);
}
}
void Check(const parser::LoopControl::Concurrent &x) {
diff --git a/flang/lib/Semantics/check-data.cpp b/flang/lib/Semantics/check-data.cpp
index 9b41a879ad700..adbcc3776b763 100644
--- a/flang/lib/Semantics/check-data.cpp
+++ b/flang/lib/Semantics/check-data.cpp
@@ -26,7 +26,7 @@ namespace Fortran::semantics {
// represented as such in the "body" of the implied DO loop.
void DataChecker::Enter(const parser::DataImpliedDo &x) {
const auto &name{parser::UnwrapRef<parser::Name>(
- std::get<parser::DataImpliedDo::Bounds>(x.t).name)};
+ std::get<parser::DataImpliedDo::Bounds>(x.t).Name())};
int kind{evaluate::ResultType<evaluate::ImpliedDoIndex>::kind};
if (const auto dynamicType{evaluate::DynamicType::From(DEREF(name.symbol))}) {
if (dynamicType->category() == TypeCategory::Integer) {
@@ -38,7 +38,7 @@ void DataChecker::Enter(const parser::DataImpliedDo &x) {
void DataChecker::Leave(const parser::DataImpliedDo &x) {
const auto &name{parser::UnwrapRef<parser::Name>(
- std::get<parser::DataImpliedDo::Bounds>(x.t).name)};
+ std::get<parser::DataImpliedDo::Bounds>(x.t).Name())};
exprAnalyzer_.RemoveImpliedDo(name.source);
}
diff --git a/flang/lib/Semantics/check-deallocate.cpp b/flang/lib/Semantics/check-deallocate.cpp
index e6ce1b30a59f5..92b75b9d2ca1d 100644
--- a/flang/lib/Semantics/check-deallocate.cpp
+++ b/flang/lib/Semantics/check-deallocate.cpp
@@ -98,10 +98,10 @@ void DeallocateChecker::Leave(const parser::DeallocateStmt &deallocateStmt) {
[&](const parser::StructureComponent &structureComponent) {
// Only perform structureComponent checks if it was successfully
// analyzed by expression analysis.
- source = structureComponent.component.source;
+ source = structureComponent.Component().source;
if (const auto *expr{GetExpr(context_, allocateObject)}) {
- if (const Symbol *symbol{structureComponent.component.symbol
- ? &structureComponent.component.symbol
+ if (const Symbol *symbol{structureComponent.Component().symbol
+ ? &structureComponent.Component().symbol
->GetUltimate()
: nullptr};
!IsAllocatableOrObjectPointer(symbol)) { // F'2023 C936
diff --git a/flang/lib/Semantics/check-do-forall.cpp b/flang/lib/Semantics/check-do-forall.cpp
index c90479d9e352e..bf92d920f282e 100644
--- a/flang/lib/Semantics/check-do-forall.cpp
+++ b/flang/lib/Semantics/check-do-forall.cpp
@@ -71,7 +71,7 @@ static const Bounds &GetBounds(const parser::DoConstruct &doConstruct) {
static const parser::Name &GetDoVariable(
const parser::DoConstruct &doConstruct) {
const Bounds &bounds{GetBounds(doConstruct)};
- return bounds.name.thing;
+ return bounds.Name().thing;
}
static parser::MessageFixedText GetEnclosingDoMsg() {
@@ -546,14 +546,14 @@ class DoContext {
// C1120 -- types of DO variables must be INTEGER, extended by allowing
// REAL and DOUBLE PRECISION
const Bounds &bounds{GetBounds(doConstruct)};
- CheckDoVariable(bounds.name);
- CheckDoExpression(bounds.lower);
- CheckDoExpression(bounds.upper);
- if (bounds.step) {
- CheckDoExpression(*bounds.step);
- if (IsZero(*bounds.step)) {
+ CheckDoVariable(bounds.Name());
+ CheckDoExpression(bounds.Lower());
+ CheckDoExpression(bounds.Upper());
+ if (auto &step{bounds.Step()}) {
+ CheckDoExpression(*step);
+ if (IsZero(*step)) {
context_.Warn(common::UsageWarning::ZeroDoStep,
- parser::UnwrapRef<parser::Expr>(bounds.step).source,
+ parser::UnwrapRef<parser::Expr>(step).source,
"DO step expression should not be zero"_warn_en_US);
}
}
@@ -1194,13 +1194,13 @@ static void CheckIoImpliedDoIndex(
void DoForallChecker::Leave(const parser::OutputImpliedDo &outputImpliedDo) {
CheckIoImpliedDoIndex(context_,
parser::UnwrapRef<parser::Name>(
- std::get<parser::IoImpliedDoControl>(outputImpliedDo.t).name));
+ std::get<parser::IoImpliedDoControl>(outputImpliedDo.t).Name()));
}
void DoForallChecker::Leave(const parser::InputImpliedDo &inputImpliedDo) {
CheckIoImpliedDoIndex(context_,
parser::UnwrapRef<parser::Name>(
- std::get<parser::IoImpliedDoControl>(inputImpliedDo.t).name));
+ std::get<parser::IoImpliedDoControl>(inputImpliedDo.t).Name()));
}
void DoForallChecker::Leave(const parser::StatVariable &statVariable) {
diff --git a/flang/lib/Semantics/check-nullify.cpp b/flang/lib/Semantics/check-nullify.cpp
index 452a891fe9bd8..db9738a452d2e 100644
--- a/flang/lib/Semantics/check-nullify.cpp
+++ b/flang/lib/Semantics/check-nullify.cpp
@@ -37,7 +37,7 @@ void NullifyChecker::Leave(const parser::NullifyStmt &nullifyStmt) {
}
},
[&](const parser::StructureComponent &structureComponent) {
- const auto &component{structureComponent.component};
+ const auto &component{structureComponent.Component()};
SourceName at{component.source};
if (const auto *checkedExpr{GetExpr(context_, pointerObject)}) {
if (auto whyNot{WhyNotDefinable(at, scope,
diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index bff00a222ba92..246ebd5ab03cc 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -489,7 +489,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
const parser::Name OmpStructureChecker::GetLoopIndex(
const parser::DoConstruct *x) {
using Bounds = parser::LoopControl::Bounds;
- return std::get<Bounds>(x->GetLoopControl()->u).name.thing;
+ return std::get<Bounds>(x->GetLoopControl()->u).Name().thing;
}
void OmpStructureChecker::SetLoopInfo(const parser::OpenMPLoopConstruct &x) {
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 2acf0dee1f77e..7ec21a25ee891 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -3637,7 +3637,7 @@ void OmpStructureChecker::CheckReductionObjects(
// a language identifier.
for (const parser::OmpObject &object : objects.v) {
if (auto *elem{GetArrayElementFromObj(object)}) {
- const parser::DataRef &base = elem->base;
+ const parser::DataRef &base = elem->Base();
if (!std::holds_alternative<parser::Name>(base.u)) {
auto source{GetObjectSource(object)};
context_.Say(source ? *source : GetContext().clauseSource,
@@ -3954,7 +3954,7 @@ bool OmpStructureChecker::IsDataRefTypeParamInquiry(
bool dataRefIsTypeParamInquiry{false};
if (const auto *structComp{
parser::Unwrap<parser::StructureComponent>(dataRef)}) {
- if (const auto *compSymbol{structComp->component.symbol}) {
+ if (const auto *compSymbol{structComp->Component().symbol}) {
if (const auto *compSymbolMiscDetails{
std::get_if<MiscDetails>(&compSymbol->details())}) {
const auto detailsKind = compSymbolMiscDetails->kind();
@@ -4624,7 +4624,7 @@ void OmpStructureChecker::CheckDoacross(const parser::OmpDoacross &doa) {
// Do-construct, collect the induction variable.
if (auto &control{(*doc)->GetLoopControl()}) {
if (auto *b{std::get_if<parser::LoopControl::Bounds>(&control->u)}) {
- inductionVars.insert(b->name.thing.symbol);
+ inductionVars.insert(b->Name().thing.symbol);
}
}
} else {
@@ -5036,10 +5036,10 @@ void OmpStructureChecker::CheckDependList(const parser::DataRef &d) {
common::visitors{
[&](const common::Indirection<parser::ArrayElement> &elem) {
// Check if the base element is valid on Depend Clause
- CheckDependList(elem.value().base);
+ CheckDependList(elem.value().Base());
},
[&](const common::Indirection<parser::StructureComponent> &comp) {
- CheckDependList(comp.value().base);
+ CheckDependList(comp.value().Base());
},
[&](const common::Indirection<parser::CoindexedNamedObject> &) {
context_.Say(GetContext().clauseSource,
@@ -5063,7 +5063,7 @@ void OmpStructureChecker::CheckArraySection(
// looking for strings.
if (!IsAssumedSizeArray(*name.symbol)) {
evaluate::ExpressionAnalyzer ea{context_};
- if (MaybeExpr expr = ea.Analyze(arrayElement.base)) {
+ if (MaybeExpr expr = ea.Analyze(arrayElement.Base())) {
if (expr->Rank() == 0) {
// Not an array: rank 0
if (std::optional<evaluate::DynamicType> type = expr->GetType()) {
@@ -5082,8 +5082,8 @@ void OmpStructureChecker::CheckArraySection(
}
}
}
- if (!arrayElement.subscripts.empty()) {
- for (const auto &subscript : arrayElement.subscripts) {
+ if (!arrayElement.Subscripts().empty()) {
+ for (const auto &subscript : arrayElement.Subscripts()) {
if (const auto *triplet{
std::get_if<parser::SubscriptTriplet>(&subscript.u)}) {
if (std::get<0>(triplet->t) && std::get<1>(triplet->t)) {
@@ -5376,7 +5376,7 @@ struct NameHelper {
return Visit(std::get<parser::DataRef>(x.t));
}
static const parser::Name *Visit(const parser::ArrayElement &x) {
- return Visit(x.base);
+ return Visit(x.Base());
}
static const parser::Name *Visit(const parser::Designator &x) {
return common::visit([](auto &&s) { return Visit(s); }, x.u);
diff --git a/flang/lib/Semantics/data-to-inits.cpp b/flang/lib/Semantics/data-to-inits.cpp
index 9012396ebf3b3..d9e79340a6d91 100644
--- a/flang/lib/Semantics/data-to-inits.cpp
+++ b/flang/lib/Semantics/data-to-inits.cpp
@@ -179,14 +179,14 @@ bool DataInitializationCompiler<DSV>::Scan(
template <typename DSV>
bool DataInitializationCompiler<DSV>::Scan(const parser::DataImpliedDo &ido) {
const auto &bounds{std::get<parser::DataImpliedDo::Bounds>(ido.t)};
- const auto &name{parser::UnwrapRef<parser::Name>(bounds.name)};
- const auto *lowerExpr{GetExpr(
- exprAnalyzer_.context(), parser::UnwrapRef<parser::Expr>(bounds.lower))};
- const auto *upperExpr{GetExpr(
- exprAnalyzer_.context(), parser::UnwrapRef<parser::Expr>(bounds.upper))};
- const auto *stepExpr{bounds.step
+ const auto &name{parser::UnwrapRef<parser::Name>(bounds.Name())};
+ const auto *lowerExpr{GetExpr(exprAnalyzer_.context(),
+ parser::UnwrapRef<parser::Expr>(bounds.Lower()))};
+ const auto *upperExpr{GetExpr(exprAnalyzer_.context(),
+ parser::UnwrapRef<parser::Expr>(bounds.Upper()))};
+ const auto *stepExpr{bounds.Step()
? GetExpr(exprAnalyzer_.context(),
- parser::UnwrapRef<parser::Expr>(bounds.step))
+ parser::UnwrapRef<parser::Expr>(bounds.Step()))
: nullptr};
if (lowerExpr && upperExpr) {
// Fold the bounds expressions (again) in case any of them depend
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index d0296e4b1f36c..6cca0c670a5f8 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -587,12 +587,12 @@ static std::optional<parser::Substring> FixMisparsedSubstringDataRef(
std::get_if<common::Indirection<parser::ArrayElement>>(&dataRef.u)}) {
// ...%a(j:k) and "a" is a character scalar
parser::ArrayElement &arrElement{ae->value()};
- if (arrElement.subscripts.size() == 1) {
+ if (arrElement.Subscripts().size() == 1) {
if (auto *triplet{std::get_if<parser::SubscriptTriplet>(
- &arrElement.subscripts.front().u)}) {
+ &arrElement.Subscripts().front().u)}) {
if (!std::get<2 /*stride*/>(triplet->t).has_value()) {
if (const Symbol *symbol{
- parser::GetLastName(arrElement.base).symbol}) {
+ parser::GetLastName(arrElement.Base()).symbol}) {
const Symbol &ultimate{symbol->GetUltimate()};
if (const semantics::DeclTypeSpec *type{ultimate.GetType()}) {
if (ultimate.Rank() == 0 &&
@@ -623,10 +623,10 @@ MaybeExpr ExpressionAnalyzer::FixMisparsedSubstring(
if (auto *sc{std::get_if<common::Indirection<parser::StructureComponent>>(
&dataRef->u)}) {
parser::StructureComponent &structComponent{sc->value()};
- parser::CharBlock which{structComponent.component.source};
+ parser::CharBlock which{structComponent.Component().source};
if (which == "kind" || which == "len") {
- if (auto substring{
- FixMisparsedSubstringDataRef(structComponent.base)}) {
+ if (auto substring{FixMisparsedSubstringDataRef(
+ std::get<parser::DataRef>(structComponent.t))}) {
// ...%a(j:k)%kind or %len and "a" is a character scalar
mutate.u = std::move(*substring);
if (MaybeExpr substringExpr{Analyze(d)}) {
@@ -1378,10 +1378,10 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::ArrayElement &ae) {
MaybeExpr baseExpr;
{
auto restorer{AllowWholeAssumedSizeArray()};
- baseExpr = Analyze(ae.base);
+ baseExpr = Analyze(ae.Base());
}
if (baseExpr) {
- if (ae.subscripts.empty()) {
+ if (ae.Subscripts().empty()) {
// will be converted to function call later or error reported
} else if (baseExpr->Rank() == 0) {
if (const Symbol *symbol{GetLastSymbol(*baseExpr)}) {
@@ -1399,14 +1399,14 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::ArrayElement &ae) {
} else if (std::optional<DataRef> dataRef{
ExtractDataRef(std::move(*baseExpr))}) {
return ApplySubscripts(
- std::move(*dataRef), AnalyzeSectionSubscripts(ae.subscripts));
+ std::move(*dataRef), AnalyzeSectionSubscripts(ae.Subscripts()));
} else {
Say("Subscripts may be applied only to an object, component, or array constant"_err_en_US);
}
}
// error was reported: analyze subscripts without reporting more errors
auto restorer{GetContextualMessages().DiscardMessages()};
- AnalyzeSectionSubscripts(ae.subscripts);
+ AnalyzeSectionSubscripts(ae.Subscripts());
return std::nullopt;
}
@@ -1460,7 +1460,7 @@ std::optional<Component> ExpressionAnalyzer::CreateComponent(DataRef &&base,
// Derived type component references and type parameter inquiries
MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) {
- Symbol *sym{sc.component.symbol};
+ Symbol *sym{sc.Component().symbol};
if (context_.HasError(sym)) {
return std::nullopt;
}
@@ -1472,14 +1472,14 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) {
MaybeExpr base;
if (isTypeParamInquiry) {
auto restorer{AllowWholeAssumedSizeArray()};
- base = Analyze(sc.base);
+ base = Analyze(sc.Base());
} else {
- base = Analyze(sc.base);
+ base = Analyze(sc.Base());
}
if (!base) {
return std::nullopt;
}
- const auto &name{sc.component.source};
+ const auto &name{sc.Component().source};
if (auto *dtExpr{UnwrapExpr<Expr<SomeDerived>>(*base)}) {
const auto *dtSpec{GetDerivedTypeSpec(dtExpr->GetType())};
if (isTypeParamInquiry) {
@@ -1551,7 +1551,8 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) {
}
MaybeExpr ExpressionAnalyzer::Analyze(const parser::CoindexedNamedObject &x) {
- if (auto dataRef{ExtractDataRef(Analyze(x.base))}) {
+ const auto &[base, selector]{x.t};
+ if (auto dataRef{ExtractDataRef(Analyze(base))}) {
if (!std::holds_alternative<ArrayRef>(dataRef->u) &&
dataRef->GetLastSymbol().Rank() > 0) { // F'2023 C916
Say("Subscripts must appear in a coindexed reference when its base is an array"_err_en_US);
@@ -1559,7 +1560,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::CoindexedNamedObject &x) {
std::vector<Expr<SubscriptInteger>> cosubscripts;
bool cosubsOk{true};
for (const auto &cosub :
- std::get<std::list<parser::Cosubscript>>(x.imageSelector.t)) {
+ std::get<std::list<parser::Cosubscript>>(selector.t)) {
MaybeExpr coex{Analyze(cosub)};
if (auto *intExpr{UnwrapExpr<Expr<SomeInteger>>(coex)}) {
cosubscripts.push_back(
@@ -1578,7 +1579,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::CoindexedNamedObject &x) {
}
CoarrayRef coarrayRef{std::move(*dataRef), std::move(cosubscripts)};
for (const auto &imageSelSpec :
- std::get<std::list<parser::ImageSelectorSpec>>(x.imageSelector.t)) {
+ std::get<std::list<parser::ImageSelectorSpec>>(selector.t)) {
common::visit(
common::visitors{
[&](const parser::ImageSelectorSpec::Notify &x) {
@@ -1969,8 +1970,8 @@ void ArrayConstructorContext::Add(const parser::Expr &expr) {
void ArrayConstructorContext::Add(const parser::AcImpliedDo &impliedDo) {
const auto &control{std::get<parser::AcImpliedDoControl>(impliedDo.t)};
const auto &bounds{std::get<parser::AcImpliedDoControl::Bounds>(control.t)};
- exprAnalyzer_.Analyze(bounds.name);
- const auto &parsedName{parser::UnwrapRef<parser::Name>(bounds.name)};
+ exprAnalyzer_.Analyze(bounds.Name());
+ const auto &parsedName{parser::UnwrapRef<parser::Name>(bounds.Name())};
parser::CharBlock name{parsedName.source};
int kind{ImpliedDoIntType::kind};
if (const Symbol *symbol{parsedName.symbol}) {
@@ -1981,12 +1982,12 @@ void ArrayConstructorContext::Add(const parser::AcImpliedDo &impliedDo) {
}
}
std::optional<Expr<ImpliedDoIntType>> lower{
- GetSpecificIntExpr<ImpliedDoIntType::kind>(bounds.lower)};
+ GetSpecificIntExpr<ImpliedDoIntType::kind>(bounds.Lower())};
std::optional<Expr<ImpliedDoIntType>> upper{
- GetSpecificIntExpr<ImpliedDoIntType::kind>(bounds.upper)};
+ GetSpecificIntExpr<ImpliedDoIntType::kind>(bounds.Upper())};
if (lower && upper) {
std::optional<Expr<ImpliedDoIntType>> stride{
- GetSpecificIntExpr<ImpliedDoIntType::kind>(bounds.step)};
+ GetSpecificIntExpr<ImpliedDoIntType::kind>(bounds.Step())};
if (!stride) {
stride = Expr<ImpliedDoIntType>{1};
}
@@ -1998,7 +1999,8 @@ void ArrayConstructorContext::Add(const parser::AcImpliedDo &impliedDo) {
auto cUpper{ToInt64(upper)};
auto cStride{ToInt64(stride)};
if (!(messageDisplayedSet_ & 0x10) && cStride && *cStride == 0) {
- exprAnalyzer_.SayAt(parser::UnwrapRef<parser::Expr>(bounds.step).source,
+ exprAnalyzer_.SayAt(
+ parser::UnwrapRef<parser::Expr>(bounds.Step()).source,
"The stride of an implied DO loop must not be zero"_err_en_US);
messageDisplayedSet_ |= 0x10;
}
@@ -2565,15 +2567,15 @@ auto ExpressionAnalyzer::AnalyzeProcedureComponentRef(
const parser::ProcComponentRef &pcr, ActualArguments &&arguments,
bool isSubroutine) -> std::optional<CalleeAndArguments> {
const auto &sc{parser::UnwrapRef<parser::StructureComponent>(pcr)};
- if (MaybeExpr base{Analyze(sc.base)}) {
- if (const Symbol *sym{sc.component.symbol}) {
+ if (MaybeExpr base{Analyze(sc.Base())}) {
+ if (const Symbol *sym{sc.Component().symbol}) {
if (context_.HasError(sym)) {
return std::nullopt;
}
if (!IsProcedure(*sym)) {
AttachDeclaration(
- Say(sc.component.source, "'%s' is not a procedure"_err_en_US,
- sc.component.source),
+ Say(sc.Component().source, "'%s' is not a procedure"_err_en_US,
+ sc.Component().source),
*sym);
return std::nullopt;
}
@@ -2628,7 +2630,7 @@ auto ExpressionAnalyzer::AnalyzeProcedureComponentRef(
sym = latest;
}
}
- sc.component.symbol = const_cast<Symbol *>(sym);
+ sc.Component().symbol = const_cast<Symbol *>(sym);
}
std::optional<DataRef> dataRef{ExtractDataRef(std::move(*dtExpr))};
if (dataRef && !CheckDataRef(*dataRef)) {
@@ -2641,11 +2643,11 @@ auto ExpressionAnalyzer::AnalyzeProcedureComponentRef(
// enforce it.
AttachDeclaration(
Warn(common::LanguageFeature::NopassScalarBase,
- sc.component.source,
+ sc.Component().source,
"Base of NOPASS type-bound procedure reference should be scalar"_port_en_US),
*sym);
} else if (IsProcedurePointer(*sym)) { // C919
- Say(sc.component.source,
+ Say(sc.Component().source,
"Base of procedure component reference must be scalar"_err_en_US);
}
}
@@ -2657,10 +2659,10 @@ auto ExpressionAnalyzer::AnalyzeProcedureComponentRef(
} else if (dataRef.has_value()) {
if (ExtractCoarrayRef(*dataRef)) {
if (IsProcedurePointer(*sym)) {
- Say(sc.component.source,
+ Say(sc.Component().source,
"Base of procedure component reference may not be coindexed"_err_en_US);
} else {
- Say(sc.component.source,
+ Say(sc.Component().source,
"A procedure binding may not be coindexed unless it can be resolved at compilation time"_err_en_US);
}
}
@@ -2674,7 +2676,7 @@ auto ExpressionAnalyzer::AnalyzeProcedureComponentRef(
std::move(arguments)};
}
}
- Say(sc.component.source,
+ Say(sc.Component().source,
"Component is not in scope of base derived type"_err_en_US);
return std::nullopt;
} else {
@@ -2686,7 +2688,7 @@ auto ExpressionAnalyzer::AnalyzeProcedureComponentRef(
}
}
}
- Say(sc.component.source,
+ Say(sc.Component().source,
"Base of procedure component reference is not a derived-type object"_err_en_US);
}
}
@@ -3360,7 +3362,7 @@ static const Symbol *AssumedTypePointerOrAllocatableDummy(const A &object) {
return common::visit(
common::visitors{
[&](const parser::StructureComponent &x) {
- return AssumedTypeDummy(x.component);
+ return AssumedTypeDummy(x.Component());
},
[&](const parser::Name &x) { return AssumedTypeDummy(x); },
},
@@ -4072,7 +4074,7 @@ static bool CheckFuncRefToArrayElement(semantics::SemanticsContext &context,
if (!name) {
name = &parser::UnwrapRef<parser::StructureComponent>(
std::get<parser::ProcComponentRef>(proc.u))
- .component;
+ .Component();
}
if (!name->symbol) {
return false;
@@ -4128,7 +4130,7 @@ static void FixMisparsedFunctionReference(
[&](parser::Name &name) { return name.symbol; },
[&](parser::ProcComponentRef &pcr) {
return parser::UnwrapRef<parser::StructureComponent>(pcr)
- .component.symbol;
+ .Component().symbol;
},
},
proc.u)}) {
@@ -5458,7 +5460,7 @@ void ExprChecker::Post(const parser::DataStmtObject &obj) {
bool ExprChecker::Pre(const parser::DataImpliedDo &ido) {
parser::Walk(std::get<parser::DataImpliedDo::Bounds>(ido.t), *this);
const auto &bounds{std::get<parser::DataImpliedDo::Bounds>(ido.t)};
- const auto &name{parser::UnwrapRef<parser::Name>(bounds.name)};
+ const auto &name{parser::UnwrapRef<parser::Name>(bounds.Name())};
int kind{evaluate::ResultType<evaluate::ImpliedDoIndex>::kind};
if (const auto dynamicType{evaluate::DynamicType::From(DEREF(name.symbol))}) {
if (dynamicType->category() == TypeCategory::Integer) {
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 6467abf872c16..101ab46a568e5 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -226,7 +226,7 @@ class AccAttributeVisitor : DirectiveAttributeVisitor<llvm::acc::Directive> {
bool Pre(const parser::LoopBounds<parser::ScalarName, A> &x) {
if (!dirContext_.empty() && GetContext().withinConstruct) {
if (auto *symbol{ResolveAcc(
- x.name.thing, Symbol::Flag::AccPrivate, currScope())}) {
+ x.Name().thing, Symbol::Flag::AccPrivate, currScope())}) {
AddToContextObjectWithDSA(*symbol, Symbol::Flag::AccPrivate);
}
}
@@ -786,9 +786,9 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
}
if (auto *procRef{
parser::Unwrap<parser::ProcComponentRef>(procD->u)}) {
- if (!procRef->v.thing.component.symbol) {
- if (!ResolveName(&procRef->v.thing.component)) {
- createDummyProcSymbol(&procRef->v.thing.component);
+ if (!procRef->v.thing.Component().symbol) {
+ if (!ResolveName(&procRef->v.thing.Component())) {
+ createDummyProcSymbol(&procRef->v.thing.Component());
}
}
}
@@ -1109,9 +1109,9 @@ std::tuple<const parser::Name *, const parser::ScalarExpr *,
DirectiveAttributeVisitor<T>::GetLoopBounds(const parser::DoConstruct &x) {
using Bounds = parser::LoopControl::Bounds;
if (x.GetLoopControl()) {
- if (const Bounds * b{std::get_if<Bounds>(&x.GetLoopControl()->u)}) {
- auto &step = b->step;
- return {&b->name.thing, &b->lower, &b->upper,
+ if (const Bounds *b{std::get_if<Bounds>(&x.GetLoopControl()->u)}) {
+ const auto &step = b->Step();
+ return {&b->Name().thing, &b->Lower(), &b->Upper(),
step.has_value() ? &step.value() : nullptr};
}
} else {
@@ -1655,12 +1655,12 @@ void AccAttributeVisitor::CheckAssociatedLoop(
if (auto *symbol{ResolveAcc(*ivName, flag, currScope())}) {
if (auto &control{loop->GetLoopControl()}) {
if (const Bounds * b{std::get_if<Bounds>(&control->u)}) {
- if (auto lowerExpr{semantics::AnalyzeExpr(context_, b->lower)}) {
+ if (auto lowerExpr{semantics::AnalyzeExpr(context_, b->Lower())}) {
semantics::UnorderedSymbolSet lowerSyms =
evaluate::CollectSymbols(*lowerExpr);
checkExprHasSymbols(ivs, lowerSyms);
}
- if (auto upperExpr{semantics::AnalyzeExpr(context_, b->upper)}) {
+ if (auto upperExpr{semantics::AnalyzeExpr(context_, b->Upper())}) {
semantics::UnorderedSymbolSet upperSyms =
evaluate::CollectSymbols(*upperExpr);
checkExprHasSymbols(ivs, upperSyms);
diff --git a/flang/lib/Semantics/resolve-names-utils.cpp b/flang/lib/Semantics/resolve-names-utils.cpp
index ac67799938013..ef34c89182f7f 100644
--- a/flang/lib/Semantics/resolve-names-utils.cpp
+++ b/flang/lib/Semantics/resolve-names-utils.cpp
@@ -519,8 +519,8 @@ bool EquivalenceSets::CheckDataRef(
return false;
},
[&](const common::Indirection<parser::ArrayElement> &elem) {
- bool ok{CheckDataRef(source, elem.value().base)};
- for (const auto &subscript : elem.value().subscripts) {
+ bool ok{CheckDataRef(source, elem.value().Base())};
+ for (const auto &subscript : elem.value().Subscripts()) {
ok &= common::visit(
common::visitors{
[&](const parser::SubscriptTriplet &) {
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 2f15ab1e82e2b..bc5f80f287636 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1532,7 +1532,7 @@ bool AccVisitor::Pre(const parser::AccClause::UseDevice &x) {
common::Indirection<parser::ArrayElement>;
if (auto *ind{std::get_if<ElementIndirection>(&dataRef->u)}) {
const parser::ArrayElement &arrayElement{ind->value()};
- const parser::DataRef &base{arrayElement.base};
+ const parser::DataRef &base{arrayElement.Base()};
if (auto *name{std::get_if<parser::Name>(&base.u)}) {
CopySymbolWithDevice(name);
}
@@ -2142,7 +2142,7 @@ class ResolveNamesVisitor : public virtual ScopeHandler,
void Post(const parser::SubstringInquiry &);
template <typename A, typename B>
void Post(const parser::LoopBounds<A, B> &x) {
- ResolveName(parser::UnwrapRef<parser::Name>(x.name));
+ ResolveName(parser::UnwrapRef<parser::Name>(x.Name()));
}
void Post(const parser::ProcComponentRef &);
bool Pre(const parser::FunctionReference &);
@@ -7936,13 +7936,13 @@ bool ConstructVisitor::Pre(const parser::AcImpliedDo &x) {
// of the implied DO variable appears in one of the bound expressions. Thus
// this extension, which shrinks the scope of the variable to exclude the
// expressions in the bounds.
- auto restore{BeginCheckOnIndexUseInOwnBounds(bounds.name)};
- Walk(bounds.lower);
- Walk(bounds.upper);
- Walk(bounds.step);
+ auto restore{BeginCheckOnIndexUseInOwnBounds(bounds.Name())};
+ Walk(bounds.Lower());
+ Walk(bounds.Upper());
+ Walk(bounds.Step());
EndCheckOnIndexUseInOwnBounds(restore);
PushScope(Scope::Kind::ImpliedDos, nullptr);
- DeclareStatementEntity(bounds.name, type);
+ DeclareStatementEntity(bounds.Name(), type);
Walk(values);
PopScope();
return false;
@@ -7953,13 +7953,13 @@ bool ConstructVisitor::Pre(const parser::DataImpliedDo &x) {
auto &type{std::get<std::optional<parser::IntegerTypeSpec>>(x.t)};
auto &bounds{std::get<parser::DataImpliedDo::Bounds>(x.t)};
// See comment in Pre(AcImpliedDo) above.
- auto restore{BeginCheckOnIndexUseInOwnBounds(bounds.name)};
- Walk(bounds.lower);
- Walk(bounds.upper);
- Walk(bounds.step);
+ auto restore{BeginCheckOnIndexUseInOwnBounds(bounds.Name())};
+ Walk(bounds.Lower());
+ Walk(bounds.Upper());
+ Walk(bounds.Step());
EndCheckOnIndexUseInOwnBounds(restore);
PushScope(Scope::Kind::ImpliedDos, nullptr);
- DeclareStatementEntity(bounds.name, type);
+ DeclareStatementEntity(bounds.Name(), type);
Walk(objects);
PopScope();
return false;
@@ -8016,7 +8016,7 @@ bool ConstructVisitor::Pre(const parser::DataStmtValue &x) {
const auto &data{std::get<parser::DataStmtConstant>(x.t)};
auto &mutableData{const_cast<parser::DataStmtConstant &>(data)};
if (auto *elem{parser::Unwrap<parser::ArrayElement>(mutableData)}) {
- if (const auto *name{std::get_if<parser::Name>(&elem->base.u)}) {
+ if (const auto *name{std::get_if<parser::Name>(&elem->Base().u)}) {
if (const Symbol * symbol{FindSymbol(*name)};
symbol && symbol->GetUltimate().has<DerivedTypeDetails>()) {
mutableData.u = elem->ConvertToStructureConstructor(
@@ -8793,7 +8793,7 @@ bool ResolveNamesVisitor::Pre(const parser::ImportStmt &x) {
const parser::Name *DeclarationVisitor::ResolveStructureComponent(
const parser::StructureComponent &x) {
- return FindComponent(ResolveDataRef(x.base), x.component);
+ return FindComponent(ResolveDataRef(x.Base()), x.Component());
}
const parser::Name *DeclarationVisitor::ResolveDesignator(
@@ -8818,8 +8818,8 @@ const parser::Name *DeclarationVisitor::ResolveDataRef(
return ResolveStructureComponent(y.value());
},
[&](const Indirection<parser::ArrayElement> &y) {
- Walk(y.value().subscripts);
- const parser::Name *name{ResolveDataRef(y.value().base)};
+ Walk(y.value().Subscripts());
+ const parser::Name *name{ResolveDataRef(y.value().Base())};
if (name && name->symbol) {
if (!IsProcedure(*name->symbol)) {
ConvertToObjectEntity(*name->symbol);
@@ -8832,8 +8832,9 @@ const parser::Name *DeclarationVisitor::ResolveDataRef(
return name;
},
[&](const Indirection<parser::CoindexedNamedObject> &y) {
- Walk(y.value().imageSelector);
- return ResolveDataRef(y.value().base);
+ const auto &[base, selector]{y.value().t};
+ Walk(selector);
+ return ResolveDataRef(base);
},
},
x.u);
@@ -9340,7 +9341,7 @@ void ResolveNamesVisitor::HandleCall(
[&](const parser::Name &x) { HandleProcedureName(procFlag, x); },
[&](const parser::ProcComponentRef &x) {
Walk(x);
- const parser::Name &name{x.v.thing.component};
+ const parser::Name &name{x.v.thing.Component()};
if (Symbol * symbol{name.symbol}) {
if (IsProcedure(*symbol)) {
SetProcFlag(name, *symbol, procFlag);
More information about the llvm-branch-commits
mailing list