FLANG

user-state.h
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 CookedSource;
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 CookedSource &cooked, common::LanguageFeatureControl features)
38 : cooked_{cooked}, features_{features} {}
39
40 const CookedSource &cooked() const { return cooked_; }
41 const common::LanguageFeatureControl &features() const { return features_; }
42
43 llvm::raw_ostream *debugOutput() const { return debugOutput_; }
44 UserState &set_debugOutput(llvm::raw_ostream &out) {
45 debugOutput_ = &out;
46 return *this;
47 }
48
49 ParsingLog *log() const { return log_; }
50 UserState &set_log(ParsingLog *log) {
51 log_ = log;
52 return *this;
53 }
54
55 bool instrumentedParse() const { return instrumentedParse_; }
56 UserState &set_instrumentedParse(bool yes) {
57 instrumentedParse_ = yes;
58 return *this;
59 }
60
61 void NewSubprogram() {
62 doLabels_.clear();
63 nonlabelDoConstructNestingDepth_ = 0;
64 oldStructureComponents_.clear();
65 }
66
67 using Label = std::uint64_t;
68 bool IsDoLabel(Label label) const {
69 auto iter{doLabels_.find(label)};
70 return iter != doLabels_.end() &&
71 iter->second >= nonlabelDoConstructNestingDepth_;
72 }
73 void NewDoLabel(Label label) {
74 doLabels_[label] = nonlabelDoConstructNestingDepth_;
75 }
76
77 void EnterNonlabelDoConstruct() { ++nonlabelDoConstructNestingDepth_; }
78 void LeaveDoConstruct() {
79 if (nonlabelDoConstructNestingDepth_ > 0) {
80 --nonlabelDoConstructNestingDepth_;
81 }
82 }
83
84 void NoteOldStructureComponent(const CharBlock &name) {
85 oldStructureComponents_.insert(name);
86 }
87 bool IsOldStructureComponent(const CharBlock &name) const {
88 return oldStructureComponents_.find(name) != oldStructureComponents_.end();
89 }
90
91 private:
92 const CookedSource &cooked_;
93
94 llvm::raw_ostream *debugOutput_{nullptr};
95
96 ParsingLog *log_{nullptr};
97 bool instrumentedParse_{false};
98
99 std::unordered_map<Label, int> doLabels_;
100 int nonlabelDoConstructNestingDepth_{0};
101
102 std::set<CharBlock> oldStructureComponents_;
103
104 common::LanguageFeatureControl features_;
105 };
106
107 // Definitions of parser classes that manipulate the UserState.
108 struct StartNewSubprogram {
109 using resultType = Success;
110 static std::optional<Success> Parse(ParseState &);
111 };
112
113 struct CapturedLabelDoStmt {
114 using resultType = Statement<common::Indirection<LabelDoStmt>>;
115 static std::optional<resultType> Parse(ParseState &);
116 };
117
118 struct EndDoStmtForCapturedLabelDoStmt {
119 using resultType = Statement<common::Indirection<EndDoStmt>>;
120 static std::optional<resultType> Parse(ParseState &);
121 };
122
123 struct EnterNonlabelDoConstruct {
124 using resultType = Success;
125 static std::optional<Success> Parse(ParseState &);
126 };
127
128 struct LeaveDoConstruct {
129 using resultType = Success;
130 static std::optional<Success> Parse(ParseState &);
131 };
132
133 struct OldStructureComponentName {
134 using resultType = Name;
135 static std::optional<Name> Parse(ParseState &);
136 };
137
138 struct StructureComponents {
139 using resultType = DataComponentDefStmt;
140 static std::optional<DataComponentDefStmt> Parse(ParseState &);
141 };
142 } // namespace Fortran::parser
143 #endif // FORTRAN_PARSER_USER_STATE_H_
Fortran::parser::Success
Definition: user-state.h:33
Fortran::parser::EndDoStmtForCapturedLabelDoStmt
Definition: user-state.h:118
Fortran::parser::Statement
Definition: parse-tree.h:344
Fortran::parser::CookedSource
Definition: provenance.h:216
Fortran::parser::LeaveDoConstruct
Definition: user-state.h:128
Fortran::common::LanguageFeatureControl
Definition: Fortran-features.h:35
Fortran::parser::EnterNonlabelDoConstruct
Definition: user-state.h:123
Fortran::parser::StartNewSubprogram
Definition: user-state.h:108
Fortran::parser::Name
Definition: parse-tree.h:555
Fortran::parser::OldStructureComponentName
Definition: user-state.h:133
Fortran::parser::CharBlock
Definition: char-block.h:28
Fortran::parser::DataComponentDefStmt
Definition: parse-tree.h:1006
Fortran::parser::ParsingLog
Definition: instrumented-parser.h:25
Fortran::parser::CapturedLabelDoStmt
Definition: user-state.h:113
Fortran::parser::StructureComponents
Definition: user-state.h:138
Fortran::parser::ParseState
Definition: parse-state.h:35
Fortran::parser
Definition: check-expression.h:19
Fortran::parser::UserState
Definition: user-state.h:35