const auto &op{*iter};
std::visit(
common::visitors{
- [&](const flat::LabelOp &linearLabel) {
+ [&](const flat::LabelOp &op) {
auto *newBlock{CreateBlock(builder_->GetCurrentRegion())};
- blockMap_.insert({linearLabel.get(), newBlock});
+ blockMap_.insert({op.get(), newBlock});
if (builder_->GetInsertionPoint()) {
builder_->CreateBranch(newBlock);
}
builder_->SetInsertionPoint(newBlock);
},
- [&](const flat::GotoOp &linearGoto) {
+ [&](const flat::GotoOp &op) {
CheckInsertionPoint();
- AddOrQueueBranch(linearGoto.target);
+ AddOrQueueBranch(op.target);
builder_->ClearInsertionPoint();
},
- [&](const flat::IndirectGotoOp &linearIGoto) {
+ [&](const flat::IndirectGotoOp &op) {
CheckInsertionPoint();
- AddOrQueueIGoto(ad, linearIGoto.symbol, linearIGoto.labelRefs);
+ AddOrQueueIGoto(ad, op.symbol, op.labelRefs);
builder_->ClearInsertionPoint();
},
- [&](const flat::ReturnOp &linearReturn) {
+ [&](const flat::ReturnOp &op) {
CheckInsertionPoint();
std::visit(
common::visitors{
builder_->CreateUnreachable();
},
},
- linearReturn.u);
+ op.u);
builder_->ClearInsertionPoint();
},
- [&](const flat::ConditionalGotoOp &linearConditionalGoto) {
+ [&](const flat::ConditionalGotoOp &cop) {
CheckInsertionPoint();
std::visit(
common::visitors{
SEMANTICS_CHECK(ExprRef(exp),
"IF THEN condition expression missing");
auto *cond{builder_->CreateExpr(ExprRef(exp))};
- AddOrQueueCGoto(cond, linearConditionalGoto.trueLabel,
- linearConditionalGoto.falseLabel);
+ AddOrQueueCGoto(cond, cop.trueLabel, cop.falseLabel);
},
[&](const parser::Statement<parser::ElseIfStmt> *s) {
const auto &exp{std::get<parser::ScalarLogicalExpr>(
SEMANTICS_CHECK(ExprRef(exp),
"ELSE IF condition expression missing");
auto *cond{builder_->CreateExpr(ExprRef(exp))};
- AddOrQueueCGoto(cond, linearConditionalGoto.trueLabel,
- linearConditionalGoto.falseLabel);
+ AddOrQueueCGoto(cond, cop.trueLabel, cop.falseLabel);
},
[&](const parser::IfStmt *s) {
const auto &exp{
SEMANTICS_CHECK(
ExprRef(exp), "IF condition expression missing");
auto *cond{builder_->CreateExpr(ExprRef(exp))};
- AddOrQueueCGoto(cond, linearConditionalGoto.trueLabel,
- linearConditionalGoto.falseLabel);
+ AddOrQueueCGoto(cond, cop.trueLabel, cop.falseLabel);
},
[&](const parser::Statement<parser::NonLabelDoStmt>
*s) {
AddOrQueueCGoto(
BuildLoopLatchExpression(&s->statement),
- linearConditionalGoto.trueLabel,
- linearConditionalGoto.falseLabel);
+ cop.trueLabel, cop.falseLabel);
}},
- linearConditionalGoto.u);
+ cop.u);
builder_->ClearInsertionPoint();
},
- [&](const flat::SwitchIOOp &linearIO) {
+ [&](const flat::SwitchIOOp &IOp) {
CheckInsertionPoint();
AddOrQueueSwitch<SwitchStmt>(
- NOTHING, linearIO.next, {}, {}, CreateSwitchHelper);
+ NOTHING, IOp.next, {}, {}, CreateSwitchHelper);
builder_->ClearInsertionPoint();
},
- [&](const flat::SwitchOp &linearSwitch) {
+ [&](const flat::SwitchOp &sop) {
CheckInsertionPoint();
std::visit(
common::visitors{
[&](auto) {
- auto args{ComposeSwitchArgs(linearSwitch)};
+ auto args{ComposeSwitchArgs(sop)};
AddOrQueueSwitch<SwitchStmt>(args.exp, args.defLab,
args.values, args.labels, CreateSwitchHelper);
},
[&](const parser::CaseConstruct *caseConstruct) {
auto args{ComposeSwitchCaseArguments(
- caseConstruct, linearSwitch.refs)};
+ caseConstruct, sop.refs)};
AddOrQueueSwitch<SwitchCaseStmt>(args.exp,
args.defLab, args.values, args.labels,
CreateSwitchCaseHelper);
[&](const parser::SelectRankConstruct
*selectRankConstruct) {
auto args{ComposeSwitchRankArguments(
- selectRankConstruct, linearSwitch.refs)};
+ selectRankConstruct, sop.refs)};
AddOrQueueSwitch<SwitchRankStmt>(args.exp,
args.defLab, args.values, args.labels,
CreateSwitchRankHelper);
[&](const parser::SelectTypeConstruct
*selectTypeConstruct) {
auto args{ComposeSwitchTypeArguments(
- selectTypeConstruct, linearSwitch.refs)};
+ selectTypeConstruct, sop.refs)};
AddOrQueueSwitch<SwitchTypeStmt>(args.exp,
args.defLab, args.values, args.labels,
CreateSwitchTypeHelper);
},
},
- linearSwitch.u);
+ sop.u);
builder_->ClearInsertionPoint();
},
[&](const flat::ActionOp &action) {
CheckInsertionPoint();
handleLinearDoCompare(cmp);
},
- [&](const flat::BeginOp &linearConstruct) {
+ [&](const flat::BeginOp &con) {
std::visit(
common::visitors{
- [&](const parser::AssociateConstruct *construct) {
+ [&](const parser::AssociateConstruct *crct) {
const auto &statement{std::get<
parser::Statement<parser::AssociateStmt>>(
- construct->t)};
+ crct->t)};
const auto &position{statement.source};
EnterRegion(position);
InitiateConstruct(&statement.statement);
},
- [&](const parser::BlockConstruct *construct) {
+ [&](const parser::BlockConstruct *crct) {
EnterRegion(
std::get<parser::Statement<parser::BlockStmt>>(
- construct->t)
+ crct->t)
.source);
},
- [&](const parser::CaseConstruct *construct) {
+ [&](const parser::CaseConstruct *crct) {
InitiateConstruct(
&std::get<
parser::Statement<parser::SelectCaseStmt>>(
- construct->t)
+ crct->t)
.statement);
},
- [&](const parser::ChangeTeamConstruct *construct) {
+ [&](const parser::ChangeTeamConstruct *crct) {
const auto &statement{std::get<
parser::Statement<parser::ChangeTeamStmt>>(
- construct->t)};
+ crct->t)};
EnterRegion(statement.source);
InitiateConstruct(&statement.statement);
},
- [&](const parser::DoConstruct *construct) {
+ [&](const parser::DoConstruct *crct) {
const auto &statement{std::get<
parser::Statement<parser::NonLabelDoStmt>>(
- construct->t)};
+ crct->t)};
EnterRegion(statement.source);
InitiateConstruct(&statement.statement);
},
- [&](const parser::IfConstruct *construct) {
+ [&](const parser::IfConstruct *crct) {
InitiateConstruct(
&std::get<parser::Statement<parser::IfThenStmt>>(
- construct->t)
+ crct->t)
.statement);
},
- [&](const parser::SelectRankConstruct *construct) {
+ [&](const parser::SelectRankConstruct *crct) {
const auto &statement{std::get<
parser::Statement<parser::SelectRankStmt>>(
- construct->t)};
+ crct->t)};
EnterRegion(statement.source);
},
- [&](const parser::SelectTypeConstruct *construct) {
+ [&](const parser::SelectTypeConstruct *crct) {
const auto &statement{std::get<
parser::Statement<parser::SelectTypeStmt>>(
- construct->t)};
+ crct->t)};
EnterRegion(statement.source);
},
- [&](const parser::WhereConstruct *construct) {
+ [&](const parser::WhereConstruct *crct) {
InitiateConstruct(
&std::get<parser::Statement<
- parser::WhereConstructStmt>>(construct->t)
+ parser::WhereConstructStmt>>(crct->t)
.statement);
},
- [&](const parser::ForallConstruct *construct) {
+ [&](const parser::ForallConstruct *crct) {
InitiateConstruct(
&std::get<parser::Statement<
- parser::ForallConstructStmt>>(construct->t)
+ parser::ForallConstructStmt>>(crct->t)
.statement);
},
[](const parser::CriticalConstruct *) { /*fixme*/ },
[](const parser::OpenMPEndLoopDirective
*) { /*fixme*/ },
},
- linearConstruct.u);
+ con.u);
auto next{iter};
const auto &nextOp{*(++next)};
std::visit(
common::visitors{
[](const auto &) {},
- [&](const flat::LabelOp &linearLabel) {
- blockMap_.insert({linearLabel.get(),
- builder_->GetInsertionPoint()});
+ [&](const flat::LabelOp &op) {
+ blockMap_.insert(
+ {op.get(), builder_->GetInsertionPoint()});
++iter;
},
},
nextOp.u);
},
- [&](const flat::EndOp &linearConstruct) {
+ [&](const flat::EndOp &con) {
std::visit(
common::visitors{
[](const auto &) {},
ExitRegion();
},
},
- linearConstruct.u);
+ con.u);
},
},
op.u);
}
}
+
void EnterRegion(const parser::CharBlock &pos) {
auto *region{builder_->GetCurrentRegion()};
auto *scope{semanticsContext_.globalScope().FindScope(pos)};
builder_->CreateBranch(block);
builder_->SetInsertionPoint(block);
}
+
void ExitRegion() {
builder_->SetCurrentRegion(builder_->GetCurrentRegion()->GetEnclosing());
}
+
void CheckInsertionPoint() {
if (!builder_->GetInsertionPoint()) {
builder_->SetInsertionPoint(CreateBlock(builder_->GetCurrentRegion()));
}
}
+
void AddOrQueueBranch(flat::LabelRef dest) {
auto iter{blockMap_.find(dest)};
if (iter != blockMap_.end()) {
builder_, builder_->GetInsertionPoint(), dest, _1));
}
}
+
void AddOrQueueCGoto(Statement *condition, flat::LabelRef trueBlock,
flat::LabelRef falseBlock) {
auto trueIter{blockMap_.find(trueBlock)};
bool LabelOp::isReferenced() const { return builder_.isReferenced(label_); }
-void AddAssign(AnalysisData &ad, const semantics::Symbol *symbol,
+static void AddAssign(AnalysisData &ad, const semantics::Symbol *symbol,
const parser::Label &label) {
ad.assignMap[symbol].insert(label);
}
return result;
}
-std::tuple<const parser::Name *, LabelRef, LabelRef> FindStack(
+static std::tuple<const parser::Name *, LabelRef, LabelRef> FindStack(
const std::vector<std::tuple<const parser::Name *, LabelRef, LabelRef>>
&stack,
const parser::Name *key) {
return iter->second;
}
-LabelOp BuildNewLabel(AnalysisData &ad) { return LabelOp{ad.labelBuilder}; }
+static LabelOp BuildNewLabel(AnalysisData &ad) {
+ return LabelOp{ad.labelBuilder};
+}
-template<typename T> parser::Label GetErr(const T &stmt) {
- if constexpr (std::is_same_v<T, parser::ReadStmt> ||
- std::is_same_v<T, parser::WriteStmt>) {
+template<typename A> parser::Label GetErr(const A &stmt) {
+ if constexpr (std::is_same_v<A, parser::ReadStmt> ||
+ std::is_same_v<A, parser::WriteStmt>) {
for (const auto &control : stmt.controls) {
if (std::holds_alternative<parser::ErrLabel>(control.u)) {
return std::get<parser::ErrLabel>(control.u).v;
}
}
}
- if constexpr (std::is_same_v<T, parser::WaitStmt> ||
- std::is_same_v<T, parser::OpenStmt> ||
- std::is_same_v<T, parser::CloseStmt> ||
- std::is_same_v<T, parser::BackspaceStmt> ||
- std::is_same_v<T, parser::EndfileStmt> ||
- std::is_same_v<T, parser::RewindStmt> ||
- std::is_same_v<T, parser::FlushStmt>) {
+ if constexpr (std::is_same_v<A, parser::WaitStmt> ||
+ std::is_same_v<A, parser::OpenStmt> ||
+ std::is_same_v<A, parser::CloseStmt> ||
+ std::is_same_v<A, parser::BackspaceStmt> ||
+ std::is_same_v<A, parser::EndfileStmt> ||
+ std::is_same_v<A, parser::RewindStmt> ||
+ std::is_same_v<A, parser::FlushStmt>) {
for (const auto &spec : stmt.v) {
if (std::holds_alternative<parser::ErrLabel>(spec.u)) {
return std::get<parser::ErrLabel>(spec.u).v;
}
}
}
- if constexpr (std::is_same_v<T, parser::InquireStmt>) {
+ if constexpr (std::is_same_v<A, parser::InquireStmt>) {
for (const auto &spec : std::get<std::list<parser::InquireSpec>>(stmt.u)) {
if (std::holds_alternative<parser::ErrLabel>(spec.u)) {
return std::get<parser::ErrLabel>(spec.u).v;
return 0;
}
-template<typename T> parser::Label GetEor(const T &stmt) {
- if constexpr (std::is_same_v<T, parser::ReadStmt> ||
- std::is_same_v<T, parser::WriteStmt>) {
+template<typename A> parser::Label GetEor(const A &stmt) {
+ if constexpr (std::is_same_v<A, parser::ReadStmt> ||
+ std::is_same_v<A, parser::WriteStmt>) {
for (const auto &control : stmt.controls) {
if (std::holds_alternative<parser::EorLabel>(control.u)) {
return std::get<parser::EorLabel>(control.u).v;
}
}
}
- if constexpr (std::is_same_v<T, parser::WaitStmt>) {
+ if constexpr (std::is_same_v<A, parser::WaitStmt>) {
for (const auto &waitSpec : stmt.v) {
if (std::holds_alternative<parser::EorLabel>(waitSpec.u)) {
return std::get<parser::EorLabel>(waitSpec.u).v;
return 0;
}
-template<typename T> parser::Label GetEnd(const T &stmt) {
- if constexpr (std::is_same_v<T, parser::ReadStmt> ||
- std::is_same_v<T, parser::WriteStmt>) {
+template<typename A> parser::Label GetEnd(const A &stmt) {
+ if constexpr (std::is_same_v<A, parser::ReadStmt> ||
+ std::is_same_v<A, parser::WriteStmt>) {
for (const auto &control : stmt.controls) {
if (std::holds_alternative<parser::EndLabel>(control.u)) {
return std::get<parser::EndLabel>(control.u).v;
}
}
}
- if constexpr (std::is_same_v<T, parser::WaitStmt>) {
+ if constexpr (std::is_same_v<A, parser::WaitStmt>) {
for (const auto &waitSpec : stmt.v) {
if (std::holds_alternative<parser::EndLabel>(waitSpec.u)) {
return std::get<parser::EndLabel>(waitSpec.u).v;
if (auto errLab{GetErr(s)}) {
std::optional<LabelRef> errRef{FetchLabel(ad, errLab).get()};
LabelOp next{BuildNewLabel(ad)};
- ops.emplace_back(SwitchIOOp{s, next, errRef});
+ ops.emplace_back(SwitchIOOp{s, next, ec.source, errRef});
ops.emplace_back(next);
} else {
ops.emplace_back(ActionOp{ec});
endRef = FetchLabel(ad, endLab).get();
}
auto next{BuildNewLabel(ad)};
- ops.emplace_back(SwitchIOOp{s, next, errRef, eorRef, endRef});
+ ops.emplace_back(SwitchIOOp{s, next, ec.source, errRef, eorRef, endRef});
ops.emplace_back(next);
} else {
ops.emplace_back(ActionOp{ec});
return result;
}
-bool hasAltReturns(const parser::CallStmt &callStmt) {
+static bool hasAltReturns(const parser::CallStmt &callStmt) {
const auto &args{std::get<std::list<parser::ActualArgSpec>>(callStmt.v.t)};
for (const auto &arg : args) {
const auto &actual{std::get<parser::ActualArg>(arg.t)};
return false;
}
-std::list<parser::Label> getAltReturnLabels(const parser::Call &call) {
+static std::list<parser::Label> getAltReturnLabels(const parser::Call &call) {
std::list<parser::Label> result;
const auto &args{std::get<std::list<parser::ActualArgSpec>>(call.t)};
for (const auto &arg : args) {
return result;
}
-LabelRef NearestEnclosingDoConstruct(AnalysisData &ad) {
+static LabelRef NearestEnclosingDoConstruct(AnalysisData &ad) {
for (auto iterator{ad.nameStack.rbegin()}, endIterator{ad.nameStack.rend()};
iterator != endIterator; ++iterator) {
auto labelReference{std::get<2>(*iterator)};
DebugChannel() << "\tgoto " << target << " ["
<< std::visit(
common::visitors{
- [](const parser::CycleStmt *s) { return "CYCLE"s; },
- [](const parser::ExitStmt *s) { return "EXIT"s; },
- [](const parser::GotoStmt *s) { return "GOTO"s; },
[](ArtificialJump) { return ""s; },
+ [&](const auto *) { return GetSource(this); },
},
u)
<< "]\n";
}
void ReturnOp::dump() const {
- DebugChannel()
- << "\treturn ["
- << std::visit(
- common::visitors{
- [](const parser::FailImageStmt *s) { return "FAIL IMAGE"s; },
- [](const parser::ReturnStmt *s) { return "RETURN"s; },
- [](const parser::StopStmt *s) { return "STOP"s; },
- },
- u)
- << "]\n";
+ DebugChannel() << "\treturn [" << GetSource(this) << "]\n";
}
void ConditionalGotoOp::dump() const {
[](const parser::Statement<parser::ElseIfStmt> *s) {
return GetSource(s);
},
- [](const parser::IfStmt *s) { return ""s; },
+ [](const parser::IfStmt *) { return "if-stmt"s; },
[](const parser::Statement<parser::NonLabelDoStmt> *s) {
return GetSource(s);
},
if (endLabel.has_value()) {
DebugChannel() << " END:" << endLabel.value();
}
- DebugChannel()
- << " ["
- << std::visit(
- common::visitors{
- [](const parser::ReadStmt *) { return "READ"s; },
- [](const parser::WriteStmt *) { return "WRITE"s; },
- [](const parser::WaitStmt *) { return "WAIT"s; },
- [](const parser::OpenStmt *) { return "OPEN"s; },
- [](const parser::CloseStmt *) { return "CLOSE"s; },
- [](const parser::BackspaceStmt *) { return "BACKSPACE"s; },
- [](const parser::EndfileStmt *) { return "ENDFILE"s; },
- [](const parser::RewindStmt *) { return "REWIND"s; },
- [](const parser::FlushStmt *) { return "FLUSH"s; },
- [](const parser::InquireStmt *) { return "INQUIRE"s; },
- },
- u)
- << "]\n";
+ DebugChannel() << " [" << GetSource(this) << "]\n";
}
void SwitchOp::dump() const {
- DebugChannel()
- << "\tswitch ["
- << std::visit(
- common::visitors{
- [](const parser::CaseConstruct *c) {
- return GetSource<parser::SelectCaseStmt>(c);
- },
- [](const parser::SelectRankConstruct *c) {
- return GetSource<parser::SelectRankStmt>(c);
- },
- [](const parser::SelectTypeConstruct *c) {
- return GetSource<parser::SelectTypeStmt>(c);
- },
- [](const parser::ComputedGotoStmt *) {
- return "computed GOTO"s;
- },
- [](const parser::ArithmeticIfStmt *) {
- return "arithmetic IF"s;
- },
- [](const parser::CallStmt *) { return "alt-return CALL"s; },
- },
- u)
- << "]\n";
+ DebugChannel() << "\tswitch [" << GetSource(this) << "]\n";
}
void ActionOp::dump() const { DebugChannel() << '\t' << GetSource(v) << '\n'; }
[](const parser::CompilerDirective *c) {
return GetSource(c);
},
- [](const parser::OpenMPConstruct *c) { return "openmp"s; },
- [](const parser::OpenMPEndLoopDirective *c) {
+ [](const parser::OpenMPConstruct *) { return "openmp"s; },
+ [](const parser::OpenMPEndLoopDirective *) {
return "openmp end loop"s;
},
},
}
void EndOp::dump() const {
- DebugChannel()
- << "\t}: ["
- << std::visit(
- common::visitors{
- [](const parser::AssociateConstruct *c) {
- return GetSource<parser::EndAssociateStmt>(c);
- },
- [](const parser::BlockConstruct *c) {
- return GetSource<parser::EndBlockStmt>(c);
- },
- [](const parser::CaseConstruct *c) {
- return GetSource<parser::EndSelectStmt>(c);
- },
- [](const parser::ChangeTeamConstruct *c) {
- return GetSource<parser::EndChangeTeamStmt>(c);
- },
- [](const parser::CriticalConstruct *c) {
- return GetSource<parser::EndCriticalStmt>(c);
- },
- [](const parser::DoConstruct *c) {
- return GetSource<parser::EndDoStmt>(c);
- },
- [](const parser::IfConstruct *c) {
- return GetSource<parser::EndIfStmt>(c);
- },
- [](const parser::SelectRankConstruct *c) {
- return GetSource<parser::EndSelectStmt>(c);
- },
- [](const parser::SelectTypeConstruct *c) {
- return GetSource<parser::EndSelectStmt>(c);
- },
- [](const parser::WhereConstruct *c) {
- return GetSource<parser::EndWhereStmt>(c);
- },
- [](const parser::ForallConstruct *c) {
- return GetSource<parser::EndForallStmt>(c);
- },
- [](const parser::CompilerDirective *c) {
- return GetSource(c);
- },
- [](const parser::OpenMPConstruct *c) { return "openmp"s; },
- [](const parser::OpenMPEndLoopDirective *c) {
- return "openmp end loop"s;
- },
- },
- u)
- << "]\n";
+ DebugChannel() << "\t}: ["
+ << std::visit(
+ common::visitors{
+ [](const parser::AssociateConstruct *c) {
+ return GetSource<parser::EndAssociateStmt>(c);
+ },
+ [](const parser::BlockConstruct *c) {
+ return GetSource<parser::EndBlockStmt>(c);
+ },
+ [](const parser::CaseConstruct *c) {
+ return GetSource<parser::EndSelectStmt>(c);
+ },
+ [](const parser::ChangeTeamConstruct *c) {
+ return GetSource<parser::EndChangeTeamStmt>(c);
+ },
+ [](const parser::CriticalConstruct *c) {
+ return GetSource<parser::EndCriticalStmt>(c);
+ },
+ [](const parser::DoConstruct *c) {
+ return GetSource<parser::EndDoStmt>(c);
+ },
+ [](const parser::IfConstruct *c) {
+ return GetSource<parser::EndIfStmt>(c);
+ },
+ [](const parser::SelectRankConstruct *c) {
+ return GetSource<parser::EndSelectStmt>(c);
+ },
+ [](const parser::SelectTypeConstruct *c) {
+ return GetSource<parser::EndSelectStmt>(c);
+ },
+ [](const parser::WhereConstruct *c) {
+ return GetSource<parser::EndWhereStmt>(c);
+ },
+ [](const parser::ForallConstruct *c) {
+ return GetSource<parser::EndForallStmt>(c);
+ },
+ [](const parser::CompilerDirective *c) {
+ return GetSource(c);
+ },
+ [](const parser::OpenMPConstruct *) {
+ return "openmp"s;
+ },
+ [](const parser::OpenMPEndLoopDirective *) {
+ return "openmp end loop"s;
+ },
+ },
+ u)
+ << "]\n";
}
void IndirectGotoOp::dump() const {
}
void DoIncrementOp::dump() const {
- DebugChannel() << "\tincrement [";
- DebugChannel() << "]\n";
+ using A = parser::Statement<parser::NonLabelDoStmt>;
+ DebugChannel() << "\tincrement [" << GetSource(&std::get<A>(v->t)) << "]\n";
}
void DoCompareOp::dump() const {
- DebugChannel() << "\tcompare [";
- DebugChannel() << "]\n";
+ using A = parser::Statement<parser::NonLabelDoStmt>;
+ DebugChannel() << "\tcompare [" << GetSource(&std::get<A>(v->t)) << "]\n";
}
void Op::Build(std::list<Op> &ops,
auto next{BuildNewLabel(ad)};
auto labels{toLabelRef(ad, getAltReturnLabels(s.value().v))};
labels.push_back(next);
- ops.emplace_back(SwitchOp{s.value(), std::move(labels)});
+ ops.emplace_back(
+ SwitchOp{s.value(), std::move(labels), ec.source});
ops.emplace_back(next);
} else {
ops.emplace_back(ActionOp{ec});
ops.emplace_back(GotoOp{s.value(),
s.value().v
? std::get<2>(FindStack(ad.nameStack, &s.value().v.value()))
- : NearestEnclosingDoConstruct(ad)});
+ : NearestEnclosingDoConstruct(ad),
+ ec.source});
},
[&](const common::Indirection<parser::ExitStmt> &s) {
ops.emplace_back(GotoOp{s.value(),
s.value().v
? std::get<1>(FindStack(ad.nameStack, &s.value().v.value()))
- : NearestEnclosingDoConstruct(ad)});
+ : NearestEnclosingDoConstruct(ad),
+ ec.source});
},
[&](const common::Indirection<parser::GotoStmt> &s) {
- ops.emplace_back(
- GotoOp{s.value(), FetchLabel(ad, s.value().v).get()});
+ ops.emplace_back(GotoOp{
+ s.value(), FetchLabel(ad, s.value().v).get(), ec.source});
},
[&](const parser::FailImageStmt &s) {
- ops.emplace_back(ReturnOp{s});
+ ops.emplace_back(ReturnOp{s, ec.source});
},
[&](const common::Indirection<parser::ReturnStmt> &s) {
- ops.emplace_back(ReturnOp{s.value()});
+ ops.emplace_back(ReturnOp{s.value(), ec.source});
},
[&](const common::Indirection<parser::StopStmt> &s) {
ops.emplace_back(ActionOp{ec});
- ops.emplace_back(ReturnOp{s.value()});
+ ops.emplace_back(ReturnOp{s.value(), ec.source});
},
[&](const common::Indirection<const parser::ReadStmt> &s) {
threeLabelSpec(s.value(), ops, ec, ad);
auto labels{toLabelRef(
ad, std::get<std::list<parser::Label>>(s.value().t))};
labels.push_back(next);
- ops.emplace_back(SwitchOp{s.value(), std::move(labels)});
+ ops.emplace_back(SwitchOp{s.value(), std::move(labels), ec.source});
ops.emplace_back(next);
},
[&](const common::Indirection<parser::ArithmeticIfStmt> &s) {
ops.emplace_back(SwitchOp{s.value(),
toLabelRef(ad,
std::list{std::get<1>(s.value().t),
- std::get<2>(s.value().t), std::get<3>(s.value().t)})});
+ std::get<2>(s.value().t), std::get<3>(s.value().t)}),
+ ec.source});
},
[&](const common::Indirection<parser::AssignedGotoStmt> &s) {
ops.emplace_back(
for (i = 0; i != N; ++i) {
targets.emplace_back(GetLabelRef(toLabels[i]));
}
- ops.emplace_back(SwitchOp{construct, targets});
+ ops.emplace_back(
+ SwitchOp{construct, targets, std::get<0>(construct.t).source});
ControlFlowAnalyzer cfa{ops, ad};
i = 0;
for (const auto &caseBlock : std::get<std::list<B>>(construct.t)) {