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 | |
17 | std::optional<Success> StartNewSubprogram::Parse(ParseState &state) { |
18 | if (auto *ustate{state.userState()}) { |
19 | ustate->NewSubprogram(); |
20 | } |
21 | return Success{}; |
22 | } |
23 | |
24 | std::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> |
37 | EndDoStmtForCapturedLabelDoStmt::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 | |
52 | std::optional<Success> EnterNonlabelDoConstruct::Parse(ParseState &state) { |
53 | if (auto *ustate{state.userState()}) { |
54 | ustate->EnterNonlabelDoConstruct(); |
55 | } |
56 | return {Success{}}; |
57 | } |
58 | |
59 | std::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 | |
71 | std::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 | |
82 | std::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 | |
98 | std::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 | |