Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions flang/include/flang/Parser/tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 &);
Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Lower/IO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -944,7 +944,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) {
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Parser/parse-tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Semantics/assignment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_;
}

Expand Down
9 changes: 6 additions & 3 deletions flang/lib/Semantics/check-allocate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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))};
Expand All @@ -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))};
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Semantics/check-case.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()};
Expand Down
9 changes: 6 additions & 3 deletions flang/lib/Semantics/check-coarray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 "
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 6 additions & 4 deletions flang/lib/Semantics/check-data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand All @@ -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);
}

Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Semantics/check-deallocate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
50 changes: 28 additions & 22 deletions flang/lib/Semantics/check-do-forall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
Expand All @@ -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);
}
}
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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}) {
Expand Down Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -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));
}
}

Expand All @@ -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
6 changes: 3 additions & 3 deletions flang/lib/Semantics/check-io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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");
Expand Down
8 changes: 4 additions & 4 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2336,7 +2336,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);
}
Expand All @@ -2350,7 +2350,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.
Expand Down Expand Up @@ -2389,8 +2389,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.
Expand Down
17 changes: 10 additions & 7 deletions flang/lib/Semantics/data-to-inits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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());
},
Expand Down
Loading