| //===-- lib/Parser/user-state.cpp -----------------------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "flang/Parser/user-state.h" | |
| #include "stmt-parser.h" | |
| #include "type-parsers.h" | |
| #include "flang/Parser/parse-state.h" | |
| #include <optional> | |
| namespace Fortran::parser { | |
| std::optional<Success> StartNewSubprogram::Parse(ParseState &state) { | |
| if (auto *ustate{state.userState()}) { | |
| ustate->NewSubprogram(); | |
| } | |
| return Success{}; | |
| } | |
| std::optional<CapturedLabelDoStmt::resultType> CapturedLabelDoStmt::Parse( | |
| ParseState &state) { | |
| static constexpr auto parser{statement(indirect(Parser<LabelDoStmt>{}))}; | |
| auto result{parser.Parse(state)}; | |
| if (result) { | |
| if (auto *ustate{state.userState()}) { | |
| ustate->NewDoLabel(std::get<Label>(result->statement.value().t)); | |
| } | |
| } | |
| return result; | |
| } | |
| std::optional<EndDoStmtForCapturedLabelDoStmt::resultType> | |
| EndDoStmtForCapturedLabelDoStmt::Parse(ParseState &state) { | |
| static constexpr auto parser{ | |
| statement(indirect(construct<EndDoStmt>("END DO" >> maybe(name))))}; | |
| if (auto enddo{parser.Parse(state)}) { | |
| if (enddo->label) { | |
| if (const auto *ustate{state.userState()}) { | |
| if (ustate->IsDoLabel(enddo->label.value())) { | |
| return enddo; | |
| } | |
| } | |
| } | |
| } | |
| return std::nullopt; | |
| } | |
| std::optional<Success> EnterNonlabelDoConstruct::Parse(ParseState &state) { | |
| if (auto *ustate{state.userState()}) { | |
| ustate->EnterNonlabelDoConstruct(); | |
| } | |
| return {Success{}}; | |
| } | |
| std::optional<Success> LeaveDoConstruct::Parse(ParseState &state) { | |
| if (auto ustate{state.userState()}) { | |
| ustate->LeaveDoConstruct(); | |
| } | |
| return {Success{}}; | |
| } | |
| // These special parsers for bits of DEC STRUCTURE capture the names of | |
| // their components and nested structures in the user state so that | |
| // references to these fields with periods can be recognized as special | |
| // cases. | |
| std::optional<Name> OldStructureComponentName::Parse(ParseState &state) { | |
| if (std::optional<Name> n{name.Parse(state)}) { | |
| if (const auto *ustate{state.userState()}) { | |
| if (ustate->IsOldStructureComponent(n->source)) { | |
| return n; | |
| } | |
| } | |
| } | |
| return std::nullopt; | |
| } | |
| std::optional<DataComponentDefStmt> StructureComponents::Parse( | |
| ParseState &state) { | |
| static constexpr auto stmt{Parser<DataComponentDefStmt>{}}; | |
| std::optional<DataComponentDefStmt> defs{stmt.Parse(state)}; | |
| if (defs) { | |
| if (auto *ustate{state.userState()}) { | |
| for (const auto &item : std::get<std::list<ComponentOrFill>>(defs->t)) { | |
| if (const auto *decl{std::get_if<ComponentDecl>(&item.u)}) { | |
| ustate->NoteOldStructureComponent(std::get<Name>(decl->t).source); | |
| } | |
| } | |
| } | |
| } | |
| return defs; | |
| } | |
| std::optional<StructureStmt> NestedStructureStmt::Parse(ParseState &state) { | |
| std::optional<StructureStmt> stmt{Parser<StructureStmt>{}.Parse(state)}; | |
| if (stmt) { | |
| if (auto *ustate{state.userState()}) { | |
| for (const auto &entity : std::get<std::list<EntityDecl>>(stmt->t)) { | |
| ustate->NoteOldStructureComponent(std::get<Name>(entity.t).source); | |
| } | |
| } | |
| } | |
| return stmt; | |
| } | |
| } // namespace Fortran::parser |