Warning: This file is not a C or C++ file. It does not have highlighting.
1 | //===-- include/flang/Parser/user-state.h -----------------------*- C++ -*-===// |
---|---|
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 | #ifndef FORTRAN_PARSER_USER_STATE_H_ |
10 | #define FORTRAN_PARSER_USER_STATE_H_ |
11 | |
12 | // Instances of ParseState (parse-state.h) incorporate instances of this |
13 | // UserState class, which encapsulates any semantic information necessary for |
14 | // parse tree construction so as to avoid any need for representing |
15 | // state in static data. |
16 | |
17 | #include "flang/Common/Fortran-features.h" |
18 | #include "flang/Common/idioms.h" |
19 | #include "flang/Parser/char-block.h" |
20 | #include "flang/Parser/parse-tree.h" |
21 | #include "llvm/Support/raw_ostream.h" |
22 | #include <cinttypes> |
23 | #include <optional> |
24 | #include <set> |
25 | #include <unordered_map> |
26 | |
27 | namespace Fortran::parser { |
28 | |
29 | class AllCookedSources; |
30 | class ParsingLog; |
31 | class ParseState; |
32 | |
33 | class Success {}; // for when one must return something that's present |
34 | |
35 | class UserState { |
36 | public: |
37 | UserState(const AllCookedSources &allCooked, |
38 | common::LanguageFeatureControl features) |
39 | : allCooked_{allCooked}, features_{features} {} |
40 | |
41 | const AllCookedSources &allCooked() const { return allCooked_; } |
42 | const common::LanguageFeatureControl &features() const { return features_; } |
43 | |
44 | llvm::raw_ostream *debugOutput() const { return debugOutput_; } |
45 | UserState &set_debugOutput(llvm::raw_ostream &out) { |
46 | debugOutput_ = &out; |
47 | return *this; |
48 | } |
49 | |
50 | ParsingLog *log() const { return log_; } |
51 | UserState &set_log(ParsingLog *log) { |
52 | log_ = log; |
53 | return *this; |
54 | } |
55 | |
56 | bool instrumentedParse() const { return instrumentedParse_; } |
57 | UserState &set_instrumentedParse(bool yes) { |
58 | instrumentedParse_ = yes; |
59 | return *this; |
60 | } |
61 | |
62 | void NewSubprogram() { |
63 | doLabels_.clear(); |
64 | nonlabelDoConstructNestingDepth_ = 0; |
65 | oldStructureComponents_.clear(); |
66 | } |
67 | |
68 | using Label = std::uint64_t; |
69 | bool IsDoLabel(Label label) const { |
70 | auto iter{doLabels_.find(label)}; |
71 | return iter != doLabels_.end() && |
72 | iter->second >= nonlabelDoConstructNestingDepth_; |
73 | } |
74 | void NewDoLabel(Label label) { |
75 | doLabels_[label] = nonlabelDoConstructNestingDepth_; |
76 | } |
77 | |
78 | void EnterNonlabelDoConstruct() { ++nonlabelDoConstructNestingDepth_; } |
79 | void LeaveDoConstruct() { |
80 | if (nonlabelDoConstructNestingDepth_ > 0) { |
81 | --nonlabelDoConstructNestingDepth_; |
82 | } |
83 | } |
84 | |
85 | void NoteOldStructureComponent(const CharBlock &name) { |
86 | oldStructureComponents_.insert(name); |
87 | } |
88 | bool IsOldStructureComponent(const CharBlock &name) const { |
89 | return oldStructureComponents_.find(name) != oldStructureComponents_.end(); |
90 | } |
91 | |
92 | private: |
93 | const AllCookedSources &allCooked_; |
94 | |
95 | llvm::raw_ostream *debugOutput_{nullptr}; |
96 | |
97 | ParsingLog *log_{nullptr}; |
98 | bool instrumentedParse_{false}; |
99 | |
100 | std::unordered_map<Label, int> doLabels_; |
101 | int nonlabelDoConstructNestingDepth_{0}; |
102 | |
103 | std::set<CharBlock> oldStructureComponents_; |
104 | |
105 | common::LanguageFeatureControl features_; |
106 | }; |
107 | |
108 | // Definitions of parser classes that manipulate the UserState. |
109 | struct StartNewSubprogram { |
110 | using resultType = Success; |
111 | static std::optional<Success> Parse(ParseState &); |
112 | }; |
113 | |
114 | struct CapturedLabelDoStmt { |
115 | using resultType = Statement<common::Indirection<LabelDoStmt>>; |
116 | static std::optional<resultType> Parse(ParseState &); |
117 | }; |
118 | |
119 | struct EndDoStmtForCapturedLabelDoStmt { |
120 | using resultType = Statement<common::Indirection<EndDoStmt>>; |
121 | static std::optional<resultType> Parse(ParseState &); |
122 | }; |
123 | |
124 | struct EnterNonlabelDoConstruct { |
125 | using resultType = Success; |
126 | static std::optional<Success> Parse(ParseState &); |
127 | }; |
128 | |
129 | struct LeaveDoConstruct { |
130 | using resultType = Success; |
131 | static std::optional<Success> Parse(ParseState &); |
132 | }; |
133 | |
134 | struct OldStructureComponentName { |
135 | using resultType = Name; |
136 | static std::optional<Name> Parse(ParseState &); |
137 | }; |
138 | |
139 | struct StructureComponents { |
140 | using resultType = DataComponentDefStmt; |
141 | static std::optional<DataComponentDefStmt> Parse(ParseState &); |
142 | }; |
143 | |
144 | struct NestedStructureStmt { |
145 | using resultType = StructureStmt; |
146 | static std::optional<StructureStmt> Parse(ParseState &); |
147 | }; |
148 | } // namespace Fortran::parser |
149 | #endif // FORTRAN_PARSER_USER_STATE_H_ |
150 |
Warning: This file is not a C or C++ file. It does not have highlighting.