1 //===-- lib/Parser/user-state.cpp -----------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "flang/Parser/user-state.h" 10 #include "stmt-parser.h" 11 #include "type-parsers.h" 12 #include "flang/Parser/parse-state.h" 13 #include <optional> 14 15 namespace Fortran::parser { 16 Parse(ParseState & state)17std::optional<Success> StartNewSubprogram::Parse(ParseState &state) { 18 if (auto *ustate{state.userState()}) { 19 ustate->NewSubprogram(); 20 } 21 return Success{}; 22 } 23 Parse(ParseState & state)24std::optional<CapturedLabelDoStmt::resultType> CapturedLabelDoStmt::Parse( 25 ParseState &state) { 26 static constexpr auto parser{statement(indirect(Parser<LabelDoStmt>{}))}; 27 auto result{parser.Parse(state)}; 28 if (result) { 29 if (auto *ustate{state.userState()}) { 30 ustate->NewDoLabel(std::get<Label>(result->statement.value().t)); 31 } 32 } 33 return result; 34 } 35 36 std::optional<EndDoStmtForCapturedLabelDoStmt::resultType> Parse(ParseState & state)37EndDoStmtForCapturedLabelDoStmt::Parse(ParseState &state) { 38 static constexpr auto parser{ 39 statement(indirect(construct<EndDoStmt>("END DO" >> maybe(name))))}; 40 if (auto enddo{parser.Parse(state)}) { 41 if (enddo->label) { 42 if (const auto *ustate{state.userState()}) { 43 if (ustate->IsDoLabel(enddo->label.value())) { 44 return enddo; 45 } 46 } 47 } 48 } 49 return std::nullopt; 50 } 51 Parse(ParseState & state)52std::optional<Success> EnterNonlabelDoConstruct::Parse(ParseState &state) { 53 if (auto *ustate{state.userState()}) { 54 ustate->EnterNonlabelDoConstruct(); 55 } 56 return {Success{}}; 57 } 58 Parse(ParseState & state)59std::optional<Success> LeaveDoConstruct::Parse(ParseState &state) { 60 if (auto ustate{state.userState()}) { 61 ustate->LeaveDoConstruct(); 62 } 63 return {Success{}}; 64 } 65 66 // These special parsers for bits of DEC STRUCTURE capture the names of 67 // their components and nested structures in the user state so that 68 // references to these fields with periods can be recognized as special 69 // cases. 70 Parse(ParseState & state)71std::optional<Name> OldStructureComponentName::Parse(ParseState &state) { 72 if (std::optional<Name> n{name.Parse(state)}) { 73 if (const auto *ustate{state.userState()}) { 74 if (ustate->IsOldStructureComponent(n->source)) { 75 return n; 76 } 77 } 78 } 79 return std::nullopt; 80 } 81 Parse(ParseState & state)82std::optional<DataComponentDefStmt> StructureComponents::Parse( 83 ParseState &state) { 84 static constexpr auto stmt{Parser<DataComponentDefStmt>{}}; 85 std::optional<DataComponentDefStmt> defs{stmt.Parse(state)}; 86 if (defs) { 87 if (auto *ustate{state.userState()}) { 88 for (const auto &item : std::get<std::list<ComponentOrFill>>(defs->t)) { 89 if (const auto *decl{std::get_if<ComponentDecl>(&item.u)}) { 90 ustate->NoteOldStructureComponent(std::get<Name>(decl->t).source); 91 } 92 } 93 } 94 } 95 return defs; 96 } 97 Parse(ParseState & state)98std::optional<StructureStmt> NestedStructureStmt::Parse(ParseState &state) { 99 std::optional<StructureStmt> stmt{Parser<StructureStmt>{}.Parse(state)}; 100 if (stmt) { 101 if (auto *ustate{state.userState()}) { 102 for (const auto &entity : std::get<std::list<EntityDecl>>(stmt->t)) { 103 ustate->NoteOldStructureComponent(std::get<Name>(entity.t).source); 104 } 105 } 106 } 107 return stmt; 108 } 109 } // namespace Fortran::parser 110