[flang-commits] [flang] e0bffe1 - [flang][NFC] Use parser::Unwrap(Ref) more (#162918)
via flang-commits
flang-commits at lists.llvm.org
Thu Oct 16 12:20:32 PDT 2025
Author: Peter Klausler
Date: 2025-10-16T12:20:27-07:00
New Revision: e0bffe1ff9082c7775063ccd52ec7213ee24f453
URL: https://github.com/llvm/llvm-project/commit/e0bffe1ff9082c7775063ccd52ec7213ee24f453
DIFF: https://github.com/llvm/llvm-project/commit/e0bffe1ff9082c7775063ccd52ec7213ee24f453.diff
LOG: [flang][NFC] Use parser::Unwrap(Ref) more (#162918)
Replace more parse tree references to "thing" and "value()" with usage
of the parser::Unwrap<> template function.
Add parser::UnwrapRef<> as an alias for DEREF(Unwrap<>()).
Added:
Modified:
flang/include/flang/Parser/tools.h
flang/lib/Lower/IO.cpp
flang/lib/Parser/parse-tree.cpp
flang/lib/Semantics/assignment.cpp
flang/lib/Semantics/check-allocate.cpp
flang/lib/Semantics/check-case.cpp
flang/lib/Semantics/check-coarray.cpp
flang/lib/Semantics/check-data.cpp
flang/lib/Semantics/check-deallocate.cpp
flang/lib/Semantics/check-do-forall.cpp
flang/lib/Semantics/check-io.cpp
flang/lib/Semantics/check-omp-structure.cpp
flang/lib/Semantics/data-to-inits.cpp
flang/lib/Semantics/expression.cpp
flang/lib/Semantics/resolve-names-utils.cpp
flang/lib/Semantics/resolve-names.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Parser/tools.h b/flang/include/flang/Parser/tools.h
index 447bccd5d35a6..a90c85625d70d 100644
--- a/flang/include/flang/Parser/tools.h
+++ b/flang/include/flang/Parser/tools.h
@@ -117,6 +117,12 @@ template <typename A, typename B> const A *Unwrap(const B &x) {
template <typename A, typename B> A *Unwrap(B &x) {
return const_cast<A *>(Unwrap<A, B>(const_cast<const B &>(x)));
}
+template <typename A, typename B> const A &UnwrapRef(const B &x) {
+ return DEREF(Unwrap<A>(x));
+}
+template <typename A, typename B> A &UnwrapRef(B &x) {
+ return DEREF(Unwrap<A>(x));
+}
// Get the CoindexedNamedObject if the entity is a coindexed object.
const CoindexedNamedObject *GetCoindexedNamedObject(const AllocateObject &);
diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp
index 604b13792fc06..cd53dc9482283 100644
--- a/flang/lib/Lower/IO.cpp
+++ b/flang/lib/Lower/IO.cpp
@@ -950,7 +950,8 @@ static void genIoLoop(Fortran::lower::AbstractConverter &converter,
makeNextConditionalOn(builder, loc, checkResult, ok, inLoop);
const auto &itemList = std::get<0>(ioImpliedDo.t);
const auto &control = std::get<1>(ioImpliedDo.t);
- const auto &loopSym = *control.name.thing.thing.symbol;
+ const auto &loopSym =
+ *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) {
diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp
index cb3093954cbe4..8cbaa399c4763 100644
--- a/flang/lib/Parser/parse-tree.cpp
+++ b/flang/lib/Parser/parse-tree.cpp
@@ -185,7 +185,7 @@ StructureConstructor ArrayElement::ConvertToStructureConstructor(
std::list<ComponentSpec> components;
for (auto &subscript : subscripts) {
components.emplace_back(std::optional<Keyword>{},
- ComponentDataSource{std::move(*Unwrap<Expr>(subscript))});
+ ComponentDataSource{std::move(UnwrapRef<Expr>(subscript))});
}
DerivedTypeSpec spec{std::move(name), std::list<TypeParamSpec>{}};
spec.derivedTypeSpec = &derived;
diff --git a/flang/lib/Semantics/assignment.cpp b/flang/lib/Semantics/assignment.cpp
index f4aa496e485e1..1824a7d232d70 100644
--- a/flang/lib/Semantics/assignment.cpp
+++ b/flang/lib/Semantics/assignment.cpp
@@ -194,7 +194,8 @@ void AssignmentContext::CheckShape(parser::CharBlock at, const SomeExpr *expr) {
template <typename A> void AssignmentContext::PushWhereContext(const A &x) {
const auto &expr{std::get<parser::LogicalExpr>(x.t)};
- CheckShape(expr.thing.value().source, GetExpr(context_, expr));
+ CheckShape(
+ parser::UnwrapRef<parser::Expr>(expr).source, GetExpr(context_, expr));
++whereDepth_;
}
diff --git a/flang/lib/Semantics/check-allocate.cpp b/flang/lib/Semantics/check-allocate.cpp
index 823aa4e795e35..0779419e62723 100644
--- a/flang/lib/Semantics/check-allocate.cpp
+++ b/flang/lib/Semantics/check-allocate.cpp
@@ -151,7 +151,9 @@ static std::optional<AllocateCheckerInfo> CheckAllocateOptions(
[&](const parser::MsgVariable &var) {
WarnOnDeferredLengthCharacterScalar(context,
GetExpr(context, var),
- var.v.thing.thing.GetSource(), "ERRMSG=");
+ parser::UnwrapRef<parser::Variable>(var)
+ .GetSource(),
+ "ERRMSG=");
if (info.gotMsg) { // C943
context.Say(
"ERRMSG may not be duplicated in a ALLOCATE statement"_err_en_US);
@@ -598,7 +600,7 @@ bool AllocationCheckerHelper::RunChecks(SemanticsContext &context) {
std::optional<evaluate::ConstantSubscript> lbound;
if (const auto &lb{std::get<0>(shapeSpec.t)}) {
lbound.reset();
- const auto &lbExpr{lb->thing.thing.value()};
+ const auto &lbExpr{parser::UnwrapRef<parser::Expr>(lb)};
if (const auto *expr{GetExpr(context, lbExpr)}) {
auto folded{
evaluate::Fold(context.foldingContext(), SomeExpr(*expr))};
@@ -609,7 +611,8 @@ bool AllocationCheckerHelper::RunChecks(SemanticsContext &context) {
lbound = 1;
}
if (lbound) {
- const auto &ubExpr{std::get<1>(shapeSpec.t).thing.thing.value()};
+ const auto &ubExpr{
+ parser::UnwrapRef<parser::Expr>(std::get<1>(shapeSpec.t))};
if (const auto *expr{GetExpr(context, ubExpr)}) {
auto folded{
evaluate::Fold(context.foldingContext(), SomeExpr(*expr))};
diff --git a/flang/lib/Semantics/check-case.cpp b/flang/lib/Semantics/check-case.cpp
index 5ce143c9aec91..7593154b84c4c 100644
--- a/flang/lib/Semantics/check-case.cpp
+++ b/flang/lib/Semantics/check-case.cpp
@@ -72,7 +72,7 @@ template <typename T> class CaseValues {
}
std::optional<Value> GetValue(const parser::CaseValue &caseValue) {
- const parser::Expr &expr{caseValue.thing.thing.value()};
+ const auto &expr{parser::UnwrapRef<parser::Expr>(caseValue)};
auto *x{expr.typedExpr.get()};
if (x && x->v) { // C1147
auto type{x->v->GetType()};
diff --git a/flang/lib/Semantics/check-coarray.cpp b/flang/lib/Semantics/check-coarray.cpp
index 0e444f155f116..91133693ff614 100644
--- a/flang/lib/Semantics/check-coarray.cpp
+++ b/flang/lib/Semantics/check-coarray.cpp
@@ -112,7 +112,7 @@ static void CheckTeamType(
static void CheckTeamStat(
SemanticsContext &context, const parser::ImageSelectorSpec::Stat &stat) {
- const parser::Variable &var{stat.v.thing.thing.value()};
+ const auto &var{parser::UnwrapRef<parser::Variable>(stat)};
if (parser::GetCoindexedNamedObject(var)) {
context.Say(parser::FindSourceLocation(var), // C931
"Image selector STAT variable must not be a coindexed "
@@ -147,7 +147,8 @@ static void CheckSyncStat(SemanticsContext &context,
},
[&](const parser::MsgVariable &var) {
WarnOnDeferredLengthCharacterScalar(context, GetExpr(context, var),
- var.v.thing.thing.GetSource(), "ERRMSG=");
+ parser::UnwrapRef<parser::Variable>(var).GetSource(),
+ "ERRMSG=");
if (gotMsg) {
context.Say( // C1172
"The errmsg-variable in a sync-stat-list may not be repeated"_err_en_US);
@@ -260,7 +261,9 @@ static void CheckEventWaitSpecList(SemanticsContext &context,
[&](const parser::MsgVariable &var) {
WarnOnDeferredLengthCharacterScalar(context,
GetExpr(context, var),
- var.v.thing.thing.GetSource(), "ERRMSG=");
+ parser::UnwrapRef<parser::Variable>(var)
+ .GetSource(),
+ "ERRMSG=");
if (gotMsg) {
context.Say( // C1178
"A errmsg-variable in a event-wait-spec-list may not be repeated"_err_en_US);
diff --git a/flang/lib/Semantics/check-data.cpp b/flang/lib/Semantics/check-data.cpp
index 5459290e59103..3bcf711735158 100644
--- a/flang/lib/Semantics/check-data.cpp
+++ b/flang/lib/Semantics/check-data.cpp
@@ -25,9 +25,10 @@ namespace Fortran::semantics {
// Ensures that references to an implied DO loop control variable are
// represented as such in the "body" of the implied DO loop.
void DataChecker::Enter(const parser::DataImpliedDo &x) {
- auto name{std::get<parser::DataImpliedDo::Bounds>(x.t).name.thing.thing};
+ const auto &name{parser::UnwrapRef<parser::Name>(
+ std::get<parser::DataImpliedDo::Bounds>(x.t).name)};
int kind{evaluate::ResultType<evaluate::ImpliedDoIndex>::kind};
- if (const auto dynamicType{evaluate::DynamicType::From(*name.symbol)}) {
+ if (const auto dynamicType{evaluate::DynamicType::From(DEREF(name.symbol))}) {
if (dynamicType->category() == TypeCategory::Integer) {
kind = dynamicType->kind();
}
@@ -36,7 +37,8 @@ void DataChecker::Enter(const parser::DataImpliedDo &x) {
}
void DataChecker::Leave(const parser::DataImpliedDo &x) {
- auto name{std::get<parser::DataImpliedDo::Bounds>(x.t).name.thing.thing};
+ const auto &name{parser::UnwrapRef<parser::Name>(
+ std::get<parser::DataImpliedDo::Bounds>(x.t).name)};
exprAnalyzer_.RemoveImpliedDo(name.source);
}
@@ -211,7 +213,7 @@ void DataChecker::Leave(const parser::DataIDoObject &object) {
std::get_if<parser::Scalar<common::Indirection<parser::Designator>>>(
&object.u)}) {
if (MaybeExpr expr{exprAnalyzer_.Analyze(*designator)}) {
- auto source{designator->thing.value().source};
+ auto source{parser::UnwrapRef<parser::Designator>(*designator).source};
DataVarChecker checker{exprAnalyzer_.context(), source};
if (checker(*expr)) {
if (checker.HasComponentWithoutSubscripts()) { // C880
diff --git a/flang/lib/Semantics/check-deallocate.cpp b/flang/lib/Semantics/check-deallocate.cpp
index c45b58586853b..c1ebc5f4c0ec2 100644
--- a/flang/lib/Semantics/check-deallocate.cpp
+++ b/flang/lib/Semantics/check-deallocate.cpp
@@ -114,7 +114,8 @@ void DeallocateChecker::Leave(const parser::DeallocateStmt &deallocateStmt) {
},
[&](const parser::MsgVariable &var) {
WarnOnDeferredLengthCharacterScalar(context_,
- GetExpr(context_, var), var.v.thing.thing.GetSource(),
+ GetExpr(context_, var),
+ parser::UnwrapRef<parser::Variable>(var).GetSource(),
"ERRMSG=");
if (gotMsg) {
context_.Say(
diff --git a/flang/lib/Semantics/check-do-forall.cpp b/flang/lib/Semantics/check-do-forall.cpp
index a2f3685950c1c..8a473406b8200 100644
--- a/flang/lib/Semantics/check-do-forall.cpp
+++ b/flang/lib/Semantics/check-do-forall.cpp
@@ -535,7 +535,8 @@ class DoContext {
if (const SomeExpr * expr{GetExpr(context_, scalarExpression)}) {
if (!ExprHasTypeCategory(*expr, TypeCategory::Integer)) {
// No warnings or errors for type INTEGER
- const parser::CharBlock &loc{scalarExpression.thing.value().source};
+ parser::CharBlock loc{
+ parser::UnwrapRef<parser::Expr>(scalarExpression).source};
CheckDoControl(loc, ExprHasTypeCategory(*expr, TypeCategory::Real));
}
}
@@ -552,7 +553,7 @@ class DoContext {
CheckDoExpression(*bounds.step);
if (IsZero(*bounds.step)) {
context_.Warn(common::UsageWarning::ZeroDoStep,
- bounds.step->thing.value().source,
+ parser::UnwrapRef<parser::Expr>(bounds.step).source,
"DO step expression should not be zero"_warn_en_US);
}
}
@@ -615,7 +616,7 @@ class DoContext {
// C1121 - procedures in mask must be pure
void CheckMaskIsPure(const parser::ScalarLogicalExpr &mask) const {
UnorderedSymbolSet references{
- GatherSymbolsFromExpression(mask.thing.thing.value())};
+ GatherSymbolsFromExpression(parser::UnwrapRef<parser::Expr>(mask))};
for (const Symbol &ref : OrderBySourcePosition(references)) {
if (IsProcedure(ref) && !IsPureProcedure(ref)) {
context_.SayWithDecl(ref, parser::Unwrap<parser::Expr>(mask)->source,
@@ -639,32 +640,33 @@ class DoContext {
}
void HasNoReferences(const UnorderedSymbolSet &indexNames,
- const parser::ScalarIntExpr &expr) const {
- CheckNoCollisions(GatherSymbolsFromExpression(expr.thing.thing.value()),
- indexNames,
+ const parser::ScalarIntExpr &scalarIntExpr) const {
+ const auto &expr{parser::UnwrapRef<parser::Expr>(scalarIntExpr)};
+ CheckNoCollisions(GatherSymbolsFromExpression(expr), indexNames,
"%s limit expression may not reference index variable '%s'"_err_en_US,
- expr.thing.thing.value().source);
+ expr.source);
}
// C1129, names in local locality-specs can't be in mask expressions
void CheckMaskDoesNotReferenceLocal(const parser::ScalarLogicalExpr &mask,
const UnorderedSymbolSet &localVars) const {
- CheckNoCollisions(GatherSymbolsFromExpression(mask.thing.thing.value()),
- localVars,
+ const auto &expr{parser::UnwrapRef<parser::Expr>(mask)};
+ CheckNoCollisions(GatherSymbolsFromExpression(expr), localVars,
"%s mask expression references variable '%s'"
" in LOCAL locality-spec"_err_en_US,
- mask.thing.thing.value().source);
+ expr.source);
}
// C1129, names in local locality-specs can't be in limit or step
// expressions
- void CheckExprDoesNotReferenceLocal(const parser::ScalarIntExpr &expr,
+ void CheckExprDoesNotReferenceLocal(
+ const parser::ScalarIntExpr &scalarIntExpr,
const UnorderedSymbolSet &localVars) const {
- CheckNoCollisions(GatherSymbolsFromExpression(expr.thing.thing.value()),
- localVars,
+ const auto &expr{parser::UnwrapRef<parser::Expr>(scalarIntExpr)};
+ CheckNoCollisions(GatherSymbolsFromExpression(expr), localVars,
"%s expression references variable '%s'"
" in LOCAL locality-spec"_err_en_US,
- expr.thing.thing.value().source);
+ expr.source);
}
// C1130, DEFAULT(NONE) locality requires names to be in locality-specs to
@@ -772,7 +774,7 @@ class DoContext {
HasNoReferences(indexNames, std::get<2>(control.t));
if (const auto &intExpr{
std::get<std::optional<parser::ScalarIntExpr>>(control.t)}) {
- const parser::Expr &expr{intExpr->thing.thing.value()};
+ const auto &expr{parser::UnwrapRef<parser::Expr>(intExpr)};
CheckNoCollisions(GatherSymbolsFromExpression(expr), indexNames,
"%s step expression may not reference index variable '%s'"_err_en_US,
expr.source);
@@ -840,7 +842,7 @@ class DoContext {
}
void CheckForImpureCall(const parser::ScalarIntExpr &x,
std::optional<IndexVarKind> nesting) const {
- const auto &parsedExpr{x.thing.thing.value()};
+ const auto &parsedExpr{parser::UnwrapRef<parser::Expr>(x)};
auto oldLocation{context_.location()};
context_.set_location(parsedExpr.source);
if (const auto &typedExpr{parsedExpr.typedExpr}) {
@@ -1124,7 +1126,8 @@ void DoForallChecker::Leave(const parser::ConnectSpec &connectSpec) {
const auto *newunit{
std::get_if<parser::ConnectSpec::Newunit>(&connectSpec.u)};
if (newunit) {
- context_.CheckIndexVarRedefine(newunit->v.thing.thing);
+ context_.CheckIndexVarRedefine(
+ parser::UnwrapRef<parser::Variable>(newunit));
}
}
@@ -1166,14 +1169,14 @@ void DoForallChecker::Leave(const parser::InquireSpec &inquireSpec) {
const auto *intVar{std::get_if<parser::InquireSpec::IntVar>(&inquireSpec.u)};
if (intVar) {
const auto &scalar{std::get<parser::ScalarIntVariable>(intVar->t)};
- context_.CheckIndexVarRedefine(scalar.thing.thing);
+ context_.CheckIndexVarRedefine(parser::UnwrapRef<parser::Variable>(scalar));
}
}
void DoForallChecker::Leave(const parser::IoControlSpec &ioControlSpec) {
const auto *size{std::get_if<parser::IoControlSpec::Size>(&ioControlSpec.u)};
if (size) {
- context_.CheckIndexVarRedefine(size->v.thing.thing);
+ context_.CheckIndexVarRedefine(parser::UnwrapRef<parser::Variable>(size));
}
}
@@ -1190,16 +1193,19 @@ static void CheckIoImpliedDoIndex(
void DoForallChecker::Leave(const parser::OutputImpliedDo &outputImpliedDo) {
CheckIoImpliedDoIndex(context_,
- std::get<parser::IoImpliedDoControl>(outputImpliedDo.t).name.thing.thing);
+ parser::UnwrapRef<parser::Name>(
+ std::get<parser::IoImpliedDoControl>(outputImpliedDo.t).name));
}
void DoForallChecker::Leave(const parser::InputImpliedDo &inputImpliedDo) {
CheckIoImpliedDoIndex(context_,
- std::get<parser::IoImpliedDoControl>(inputImpliedDo.t).name.thing.thing);
+ parser::UnwrapRef<parser::Name>(
+ std::get<parser::IoImpliedDoControl>(inputImpliedDo.t).name));
}
void DoForallChecker::Leave(const parser::StatVariable &statVariable) {
- context_.CheckIndexVarRedefine(statVariable.v.thing.thing);
+ context_.CheckIndexVarRedefine(
+ parser::UnwrapRef<parser::Variable>(statVariable));
}
} // namespace Fortran::semantics
diff --git a/flang/lib/Semantics/check-io.cpp b/flang/lib/Semantics/check-io.cpp
index a1ff4b922268b..19059ad1b1223 100644
--- a/flang/lib/Semantics/check-io.cpp
+++ b/flang/lib/Semantics/check-io.cpp
@@ -424,8 +424,8 @@ void IoChecker::Enter(const parser::InquireSpec::CharVar &spec) {
specKind = IoSpecKind::Dispose;
break;
}
- const parser::Variable &var{
- std::get<parser::ScalarDefaultCharVariable>(spec.t).thing.thing};
+ const auto &var{parser::UnwrapRef<parser::Variable>(
+ std::get<parser::ScalarDefaultCharVariable>(spec.t))};
std::string what{parser::ToUpperCaseLetters(common::EnumToString(specKind))};
CheckForDefinableVariable(var, what);
WarnOnDeferredLengthCharacterScalar(
@@ -627,7 +627,7 @@ void IoChecker::Enter(const parser::IoUnit &spec) {
}
void IoChecker::Enter(const parser::MsgVariable &msgVar) {
- const parser::Variable &var{msgVar.v.thing.thing};
+ const auto &var{parser::UnwrapRef<parser::Variable>(msgVar)};
if (stmt_ == IoStmtKind::None) {
// allocate, deallocate, image control
CheckForDefinableVariable(var, "ERRMSG");
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index b4c1bf7424eac..ea6fe43f07de8 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -2358,7 +2358,7 @@ struct TaskgraphVisitor {
}
if (auto &repl{std::get<parser::OmpClause::Replayable>(clause.u).v}) {
// Scalar<Logical<Constant<indirection<Expr>>>>
- const parser::Expr &parserExpr{repl->v.thing.thing.thing.value()};
+ const auto &parserExpr{parser::UnwrapRef<parser::Expr>(repl)};
if (auto &&expr{GetEvaluateExpr(parserExpr)}) {
return GetLogicalValue(*expr).value_or(true);
}
@@ -2372,7 +2372,7 @@ struct TaskgraphVisitor {
bool isTransparent{true};
if (auto &transp{std::get<parser::OmpClause::Transparent>(clause.u).v}) {
// Scalar<Integer<indirection<Expr>>>
- const parser::Expr &parserExpr{transp->v.thing.thing.value()};
+ const auto &parserExpr{parser::UnwrapRef<parser::Expr>(transp)};
if (auto &&expr{GetEvaluateExpr(parserExpr)}) {
// If the argument is omp_not_impex (defined as 0), then
// the task is not transparent, otherwise it is.
@@ -2411,8 +2411,8 @@ struct TaskgraphVisitor {
}
}
// Scalar<Logical<indirection<Expr>>>
- auto &parserExpr{
- std::get<parser::ScalarLogicalExpr>(ifc.v.t).thing.thing.value()};
+ const auto &parserExpr{parser::UnwrapRef<parser::Expr>(
+ std::get<parser::ScalarLogicalExpr>(ifc.v.t))};
if (auto &&expr{GetEvaluateExpr(parserExpr)}) {
// If the value is known to be false, an undeferred task will be
// generated.
diff --git a/flang/lib/Semantics/data-to-inits.cpp b/flang/lib/Semantics/data-to-inits.cpp
index 1e46dabe30c89..bbf3b28fe03e6 100644
--- a/flang/lib/Semantics/data-to-inits.cpp
+++ b/flang/lib/Semantics/data-to-inits.cpp
@@ -179,13 +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)};
- auto name{bounds.name.thing.thing};
- const auto *lowerExpr{
- GetExpr(exprAnalyzer_.context(), bounds.lower.thing.thing)};
- const auto *upperExpr{
- GetExpr(exprAnalyzer_.context(), bounds.upper.thing.thing)};
+ 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(), bounds.step->thing.thing)
+ ? GetExpr(exprAnalyzer_.context(),
+ parser::UnwrapRef<parser::Expr>(bounds.step))
: nullptr};
if (lowerExpr && upperExpr) {
// Fold the bounds expressions (again) in case any of them depend
@@ -240,7 +241,9 @@ bool DataInitializationCompiler<DSV>::Scan(
return common::visit(
common::visitors{
[&](const parser::Scalar<common::Indirection<parser::Designator>>
- &var) { return Scan(var.thing.value()); },
+ &var) {
+ return Scan(parser::UnwrapRef<parser::Designator>(var));
+ },
[&](const common::Indirection<parser::DataImpliedDo> &ido) {
return Scan(ido.value());
},
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 2feec98eead83..f04000883f781 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -1954,9 +1954,10 @@ 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);
- parser::CharBlock name{bounds.name.thing.thing.source};
+ const auto &parsedName{parser::UnwrapRef<parser::Name>(bounds.name)};
+ parser::CharBlock name{parsedName.source};
int kind{ImpliedDoIntType::kind};
- if (const Symbol * symbol{bounds.name.thing.thing.symbol}) {
+ if (const Symbol *symbol{parsedName.symbol}) {
if (auto dynamicType{DynamicType::From(symbol)}) {
if (dynamicType->category() == TypeCategory::Integer) {
kind = dynamicType->kind();
@@ -1981,7 +1982,7 @@ void ArrayConstructorContext::Add(const parser::AcImpliedDo &impliedDo) {
auto cUpper{ToInt64(upper)};
auto cStride{ToInt64(stride)};
if (!(messageDisplayedSet_ & 0x10) && cStride && *cStride == 0) {
- exprAnalyzer_.SayAt(bounds.step.value().thing.thing.value().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;
}
@@ -2526,7 +2527,7 @@ static const Symbol *GetBindingResolution(
auto ExpressionAnalyzer::AnalyzeProcedureComponentRef(
const parser::ProcComponentRef &pcr, ActualArguments &&arguments,
bool isSubroutine) -> std::optional<CalleeAndArguments> {
- const parser::StructureComponent &sc{pcr.v.thing};
+ const auto &sc{parser::UnwrapRef<parser::StructureComponent>(pcr)};
if (MaybeExpr base{Analyze(sc.base)}) {
if (const Symbol *sym{sc.component.symbol}) {
if (context_.HasError(sym)) {
@@ -3997,7 +3998,9 @@ static bool CheckFuncRefToArrayElement(semantics::SemanticsContext &context,
auto &proc{std::get<parser::ProcedureDesignator>(funcRef.v.t)};
const auto *name{std::get_if<parser::Name>(&proc.u)};
if (!name) {
- name = &std::get<parser::ProcComponentRef>(proc.u).v.thing.component;
+ name = &parser::UnwrapRef<parser::StructureComponent>(
+ std::get<parser::ProcComponentRef>(proc.u))
+ .component;
}
if (!name->symbol) {
return false;
@@ -4047,14 +4050,16 @@ static void FixMisparsedFunctionReference(
}
}
auto &proc{std::get<parser::ProcedureDesignator>(funcRef.v.t)};
- if (Symbol *origSymbol{
- common::visit(common::visitors{
- [&](parser::Name &name) { return name.symbol; },
- [&](parser::ProcComponentRef &pcr) {
- return pcr.v.thing.component.symbol;
- },
- },
- proc.u)}) {
+ if (Symbol *
+ origSymbol{common::visit(
+ common::visitors{
+ [&](parser::Name &name) { return name.symbol; },
+ [&](parser::ProcComponentRef &pcr) {
+ return parser::UnwrapRef<parser::StructureComponent>(pcr)
+ .component.symbol;
+ },
+ },
+ proc.u)}) {
Symbol &symbol{origSymbol->GetUltimate()};
if (symbol.has<semantics::ObjectEntityDetails>() ||
symbol.has<semantics::AssocEntityDetails>()) {
@@ -5268,9 +5273,9 @@ 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)};
- auto name{bounds.name.thing.thing};
+ const auto &name{parser::UnwrapRef<parser::Name>(bounds.name)};
int kind{evaluate::ResultType<evaluate::ImpliedDoIndex>::kind};
- if (const auto dynamicType{evaluate::DynamicType::From(*name.symbol)}) {
+ if (const auto dynamicType{evaluate::DynamicType::From(DEREF(name.symbol))}) {
if (dynamicType->category() == TypeCategory::Integer) {
kind = dynamicType->kind();
}
diff --git a/flang/lib/Semantics/resolve-names-utils.cpp b/flang/lib/Semantics/resolve-names-utils.cpp
index 742bb748b7ff3..ac67799938013 100644
--- a/flang/lib/Semantics/resolve-names-utils.cpp
+++ b/flang/lib/Semantics/resolve-names-utils.cpp
@@ -492,12 +492,14 @@ bool EquivalenceSets::CheckDesignator(const parser::Designator &designator) {
const auto &range{std::get<parser::SubstringRange>(x.t)};
bool ok{CheckDataRef(designator.source, dataRef)};
if (const auto &lb{std::get<0>(range.t)}) {
- ok &= CheckSubstringBound(lb->thing.thing.value(), true);
+ ok &= CheckSubstringBound(
+ parser::UnwrapRef<parser::Expr>(lb), true);
} else {
currObject_.substringStart = 1;
}
if (const auto &ub{std::get<1>(range.t)}) {
- ok &= CheckSubstringBound(ub->thing.thing.value(), false);
+ ok &= CheckSubstringBound(
+ parser::UnwrapRef<parser::Expr>(ub), false);
}
return ok;
},
@@ -528,7 +530,8 @@ bool EquivalenceSets::CheckDataRef(
return false;
},
[&](const parser::IntExpr &y) {
- return CheckArrayBound(y.thing.value());
+ return CheckArrayBound(
+ parser::UnwrapRef<parser::Expr>(y));
},
},
subscript.u);
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index ae0ff9ca8068d..699de417a629f 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1140,7 +1140,7 @@ class DeclarationVisitor : public ArraySpecVisitor,
std::optional<SourceName> BeginCheckOnIndexUseInOwnBounds(
const parser::DoVariable &name) {
std::optional<SourceName> result{checkIndexUseInOwnBounds_};
- checkIndexUseInOwnBounds_ = name.thing.thing.source;
+ checkIndexUseInOwnBounds_ = parser::UnwrapRef<parser::Name>(name).source;
return result;
}
void EndCheckOnIndexUseInOwnBounds(const std::optional<SourceName> &restore) {
@@ -2130,7 +2130,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::Unwrap<parser::Name>(x.name));
+ ResolveName(parser::UnwrapRef<parser::Name>(x.name));
}
void Post(const parser::ProcComponentRef &);
bool Pre(const parser::FunctionReference &);
@@ -2560,7 +2560,7 @@ KindExpr DeclTypeSpecVisitor::GetKindParamExpr(
CHECK(!state_.originalKindParameter);
// Save a pointer to the KIND= expression in the parse tree
// in case we need to reanalyze it during PDT instantiation.
- state_.originalKindParameter = &expr->thing.thing.thing.value();
+ state_.originalKindParameter = parser::Unwrap<parser::Expr>(expr);
}
}
// Inhibit some errors now that will be caught later during instantiations.
@@ -5649,6 +5649,7 @@ bool DeclarationVisitor::Pre(const parser::NamedConstantDef &x) {
if (details->init() || symbol.test(Symbol::Flag::InDataStmt)) {
Say(name, "Named constant '%s' already has a value"_err_en_US);
}
+ parser::CharBlock at{parser::UnwrapRef<parser::Expr>(expr).source};
if (inOldStyleParameterStmt_) {
// non-standard extension PARAMETER statement (no parentheses)
Walk(expr);
@@ -5657,7 +5658,6 @@ bool DeclarationVisitor::Pre(const parser::NamedConstantDef &x) {
SayWithDecl(name, symbol,
"Alternative style PARAMETER '%s' must not already have an explicit type"_err_en_US);
} else if (folded) {
- auto at{expr.thing.value().source};
if (evaluate::IsActuallyConstant(*folded)) {
if (const auto *type{currScope().GetType(*folded)}) {
if (type->IsPolymorphic()) {
@@ -5682,8 +5682,7 @@ bool DeclarationVisitor::Pre(const parser::NamedConstantDef &x) {
// standard-conforming PARAMETER statement (with parentheses)
ApplyImplicitRules(symbol);
Walk(expr);
- if (auto converted{EvaluateNonPointerInitializer(
- symbol, expr, expr.thing.value().source)}) {
+ if (auto converted{EvaluateNonPointerInitializer(symbol, expr, at)}) {
details->set_init(std::move(*converted));
}
}
@@ -6149,7 +6148,7 @@ bool DeclarationVisitor::Pre(const parser::KindParam &x) {
if (const auto *kind{std::get_if<
parser::Scalar<parser::Integer<parser::Constant<parser::Name>>>>(
&x.u)}) {
- const parser::Name &name{kind->thing.thing.thing};
+ const auto &name{parser::UnwrapRef<parser::Name>(kind)};
if (!FindSymbol(name)) {
Say(name, "Parameter '%s' not found"_err_en_US);
}
@@ -7460,7 +7459,7 @@ void DeclarationVisitor::DeclareLocalEntity(
Symbol *DeclarationVisitor::DeclareStatementEntity(
const parser::DoVariable &doVar,
const std::optional<parser::IntegerTypeSpec> &type) {
- const parser::Name &name{doVar.thing.thing};
+ const auto &name{parser::UnwrapRef<parser::Name>(doVar)};
const DeclTypeSpec *declTypeSpec{nullptr};
if (auto *prev{FindSymbol(name)}) {
if (prev->owner() == currScope()) {
@@ -7893,13 +7892,14 @@ bool ConstructVisitor::Pre(const parser::DataIDoObject &x) {
common::visit(
common::visitors{
[&](const parser::Scalar<Indirection<parser::Designator>> &y) {
- Walk(y.thing.value());
- const parser::Name &first{parser::GetFirstName(y.thing.value())};
+ const auto &designator{parser::UnwrapRef<parser::Designator>(y)};
+ Walk(designator);
+ const parser::Name &first{parser::GetFirstName(designator)};
if (first.symbol) {
first.symbol->set(Symbol::Flag::InDataStmt);
}
},
- [&](const Indirection<parser::DataImpliedDo> &y) { Walk(y.value()); },
+ [&](const Indirection<parser::DataImpliedDo> &y) { Walk(y); },
},
x.u);
return false;
@@ -8582,8 +8582,7 @@ class ExecutionPartAsyncIOSkimmer : public ExecutionPartSkimmerBase {
void Post(const parser::WriteStmt &) { inAsyncIO_ = false; }
void Post(const parser::IoControlSpec::Size &size) {
if (const auto *designator{
- std::get_if<common::Indirection<parser::Designator>>(
- &size.v.thing.thing.u)}) {
+ parser::Unwrap<common::Indirection<parser::Designator>>(size)}) {
NoteAsyncIODesignator(designator->value());
}
}
@@ -9175,16 +9174,17 @@ bool DeclarationVisitor::CheckNonPointerInitialization(
}
void DeclarationVisitor::NonPointerInitialization(
- const parser::Name &name, const parser::ConstantExpr &expr) {
+ const parser::Name &name, const parser::ConstantExpr &constExpr) {
if (CheckNonPointerInitialization(
name, /*inLegacyDataInitialization=*/false)) {
Symbol &ultimate{name.symbol->GetUltimate()};
auto &details{ultimate.get<ObjectEntityDetails>()};
+ const auto &expr{parser::UnwrapRef<parser::Expr>(constExpr)};
if (ultimate.owner().IsParameterizedDerivedType()) {
// Save the expression for per-instantiation analysis.
- details.set_unanalyzedPDTComponentInit(&expr.thing.value());
+ details.set_unanalyzedPDTComponentInit(&expr);
} else if (MaybeExpr folded{EvaluateNonPointerInitializer(
- ultimate, expr, expr.thing.value().source)}) {
+ ultimate, constExpr, expr.source)}) {
details.set_init(std::move(*folded));
ultimate.set(Symbol::Flag::InDataStmt, false);
}
More information about the flang-commits
mailing list