bool Pre(const parser::WhereConstructStmt &x) { return CheckDef(x.t); }
bool Pre(const parser::ForallConstructStmt &x) { return CheckDef(x.t); }
bool Pre(const parser::CriticalStmt &x) { return CheckDef(x.t); }
- bool Pre(const parser::LabelDoStmt &x) { common::die("should not happen"); }
+ bool Pre(const parser::LabelDoStmt &x) {
+ return false; // error recovery
+ }
bool Pre(const parser::NonLabelDoStmt &x) { return CheckDef(x.t); }
bool Pre(const parser::IfThenStmt &x) { return CheckDef(x.t); }
bool Pre(const parser::SelectCaseStmt &x) { return CheckDef(x.t); }
void ScopeHandler::PopScope() {
// Entities that are not yet classified as objects or procedures are now
// assumed to be objects.
+ // TODO: Statement functions
for (auto &pair : currScope()) {
ConvertToObjectEntity(*pair.second);
}
const auto &name{std::get<parser::Name>(stmt.t)};
auto &details{PostSubprogramStmt(name)};
for (const auto &dummyArg : std::get<std::list<parser::DummyArg>>(stmt.t)) {
- const parser::Name *dummyName = std::get_if<parser::Name>(&dummyArg.u);
- CHECK(dummyName != nullptr && "TODO: alternate return indicator");
- Symbol &dummy{MakeSymbol(*dummyName, EntityDetails(true))};
- details.add_dummyArg(dummy);
+ if (const auto *dummyName{std::get_if<parser::Name>(&dummyArg.u)}) {
+ Symbol &dummy{MakeSymbol(*dummyName, EntityDetails(true))};
+ details.add_dummyArg(dummy);
+ } else {
+ details.add_alternateReturn();
+ }
}
}
}
const std::list<Symbol *> &dummyArgs() const { return dummyArgs_; }
void add_dummyArg(Symbol &symbol) { dummyArgs_.push_back(&symbol); }
+ void add_alternateReturn() { dummyArgs_.push_back(nullptr); }
private:
bool isInterface_{false}; // true if this represents an interface-body
MaybeExpr bindName_;
- std::list<Symbol *> dummyArgs_;
+ std::list<Symbol *> dummyArgs_; // nullptr -> alternate return indicator
Symbol *result_{nullptr};
friend std::ostream &operator<<(std::ostream &, const SubprogramDetails &);
};