10
10
#include " flang/Common/idioms.h"
11
11
#include " flang/Parser/char-block.h"
12
12
#include " flang/Semantics/scope.h"
13
+ #include " flang/Semantics/semantics.h"
13
14
14
15
namespace Fortran ::semantics {
15
16
@@ -76,7 +77,8 @@ static void GetGenerics(
76
77
}
77
78
78
79
template <typename T>
79
- static ProgramTree BuildSubprogramTree (const parser::Name &name, const T &x) {
80
+ static ProgramTree BuildSubprogramTree (
81
+ const parser::Name &name, SemanticsContext &context, const T &x) {
80
82
const auto &spec{std::get<parser::SpecificationPart>(x.t )};
81
83
const auto &exec{std::get<parser::ExecutionPart>(x.t )};
82
84
const auto &subps{
@@ -89,21 +91,26 @@ static ProgramTree BuildSubprogramTree(const parser::Name &name, const T &x) {
89
91
for (const auto &subp :
90
92
std::get<std::list<parser::InternalSubprogram>>(subps->t )) {
91
93
common::visit (
92
- [&](const auto &y) { node.AddChild (ProgramTree::Build (y.value ())); },
94
+ [&](const auto &y) {
95
+ if (auto child{ProgramTree::Build (y.value (), context)}) {
96
+ node.AddChild (std::move (*child));
97
+ }
98
+ },
93
99
subp.u );
94
100
}
95
101
}
96
102
return node;
97
103
}
98
104
99
105
static ProgramTree BuildSubprogramTree (
100
- const parser::Name &name, const parser::BlockData &x) {
106
+ const parser::Name &name, SemanticsContext &, const parser::BlockData &x) {
101
107
const auto &spec{std::get<parser::SpecificationPart>(x.t )};
102
108
return ProgramTree{name, spec};
103
109
}
104
110
105
111
template <typename T>
106
- static ProgramTree BuildModuleTree (const parser::Name &name, const T &x) {
112
+ static ProgramTree BuildModuleTree (
113
+ const parser::Name &name, SemanticsContext &context, const T &x) {
107
114
const auto &spec{std::get<parser::SpecificationPart>(x.t )};
108
115
const auto &subps{std::get<std::optional<parser::ModuleSubprogramPart>>(x.t )};
109
116
ProgramTree node{name, spec};
@@ -112,28 +119,42 @@ static ProgramTree BuildModuleTree(const parser::Name &name, const T &x) {
112
119
for (const auto &subp :
113
120
std::get<std::list<parser::ModuleSubprogram>>(subps->t )) {
114
121
common::visit (
115
- [&](const auto &y) { node.AddChild (ProgramTree::Build (y.value ())); },
122
+ [&](const auto &y) {
123
+ if (auto child{ProgramTree::Build (y.value (), context)}) {
124
+ node.AddChild (std::move (*child));
125
+ }
126
+ },
116
127
subp.u );
117
128
}
118
129
}
119
130
return node;
120
131
}
121
132
122
- ProgramTree ProgramTree::Build (const parser::ProgramUnit &x) {
123
- return common::visit ([](const auto &y) { return Build (y.value ()); }, x.u );
133
+ ProgramTree ProgramTree::Build (
134
+ const parser::ProgramUnit &x, SemanticsContext &context) {
135
+ return common::visit (
136
+ [&](const auto &y) {
137
+ auto node{Build (y.value (), context)};
138
+ CHECK (node.has_value ());
139
+ return std::move (*node);
140
+ },
141
+ x.u );
124
142
}
125
143
126
- ProgramTree ProgramTree::Build (const parser::MainProgram &x) {
144
+ std::optional<ProgramTree> ProgramTree::Build (
145
+ const parser::MainProgram &x, SemanticsContext &context) {
127
146
const auto &stmt{
128
147
std::get<std::optional<parser::Statement<parser::ProgramStmt>>>(x.t )};
129
148
const auto &end{std::get<parser::Statement<parser::EndProgramStmt>>(x.t )};
130
149
static parser::Name emptyName;
131
- auto result{stmt ? BuildSubprogramTree (stmt->statement .v , x).set_stmt (*stmt)
132
- : BuildSubprogramTree (emptyName, x)};
133
- return result.set_endStmt (end);
150
+ auto result{stmt
151
+ ? BuildSubprogramTree (stmt->statement .v , context, x).set_stmt (*stmt)
152
+ : BuildSubprogramTree (emptyName, context, x)};
153
+ return std::move (result.set_endStmt (end));
134
154
}
135
155
136
- ProgramTree ProgramTree::Build (const parser::FunctionSubprogram &x) {
156
+ std::optional<ProgramTree> ProgramTree::Build (
157
+ const parser::FunctionSubprogram &x, SemanticsContext &context) {
137
158
const auto &stmt{std::get<parser::Statement<parser::FunctionStmt>>(x.t )};
138
159
const auto &end{std::get<parser::Statement<parser::EndFunctionStmt>>(x.t )};
139
160
const auto &name{std::get<parser::Name>(stmt.statement .t )};
@@ -144,13 +165,14 @@ ProgramTree ProgramTree::Build(const parser::FunctionSubprogram &x) {
144
165
bindingSpec = &*suffix->binding ;
145
166
}
146
167
}
147
- return BuildSubprogramTree (name, x)
168
+ return BuildSubprogramTree (name, context, x)
148
169
.set_stmt (stmt)
149
170
.set_endStmt (end)
150
171
.set_bindingSpec (bindingSpec);
151
172
}
152
173
153
- ProgramTree ProgramTree::Build (const parser::SubroutineSubprogram &x) {
174
+ std::optional<ProgramTree> ProgramTree::Build (
175
+ const parser::SubroutineSubprogram &x, SemanticsContext &context) {
154
176
const auto &stmt{std::get<parser::Statement<parser::SubroutineStmt>>(x.t )};
155
177
const auto &end{std::get<parser::Statement<parser::EndSubroutineStmt>>(x.t )};
156
178
const auto &name{std::get<parser::Name>(stmt.statement .t )};
@@ -159,48 +181,56 @@ ProgramTree ProgramTree::Build(const parser::SubroutineSubprogram &x) {
159
181
stmt.statement .t )}) {
160
182
bindingSpec = &*binding;
161
183
}
162
- return BuildSubprogramTree (name, x)
184
+ return BuildSubprogramTree (name, context, x)
163
185
.set_stmt (stmt)
164
186
.set_endStmt (end)
165
187
.set_bindingSpec (bindingSpec);
166
188
}
167
189
168
- ProgramTree ProgramTree::Build (const parser::SeparateModuleSubprogram &x) {
190
+ std::optional<ProgramTree> ProgramTree::Build (
191
+ const parser::SeparateModuleSubprogram &x, SemanticsContext &context) {
169
192
const auto &stmt{std::get<parser::Statement<parser::MpSubprogramStmt>>(x.t )};
170
193
const auto &end{
171
194
std::get<parser::Statement<parser::EndMpSubprogramStmt>>(x.t )};
172
195
const auto &name{stmt.statement .v };
173
- return BuildSubprogramTree (name, x).set_stmt (stmt).set_endStmt (end);
196
+ return BuildSubprogramTree (name, context, x).set_stmt (stmt).set_endStmt (end);
174
197
}
175
198
176
- ProgramTree ProgramTree::Build (const parser::Module &x) {
199
+ std::optional<ProgramTree> ProgramTree::Build (
200
+ const parser::Module &x, SemanticsContext &context) {
177
201
const auto &stmt{std::get<parser::Statement<parser::ModuleStmt>>(x.t )};
178
202
const auto &end{std::get<parser::Statement<parser::EndModuleStmt>>(x.t )};
179
203
const auto &name{stmt.statement .v };
180
- return BuildModuleTree (name, x).set_stmt (stmt).set_endStmt (end);
204
+ return BuildModuleTree (name, context, x).set_stmt (stmt).set_endStmt (end);
181
205
}
182
206
183
- ProgramTree ProgramTree::Build (const parser::Submodule &x) {
207
+ std::optional<ProgramTree> ProgramTree::Build (
208
+ const parser::Submodule &x, SemanticsContext &context) {
184
209
const auto &stmt{std::get<parser::Statement<parser::SubmoduleStmt>>(x.t )};
185
210
const auto &end{std::get<parser::Statement<parser::EndSubmoduleStmt>>(x.t )};
186
211
const auto &name{std::get<parser::Name>(stmt.statement .t )};
187
- return BuildModuleTree (name, x).set_stmt (stmt).set_endStmt (end);
212
+ return BuildModuleTree (name, context, x).set_stmt (stmt).set_endStmt (end);
188
213
}
189
214
190
- ProgramTree ProgramTree::Build (const parser::BlockData &x) {
215
+ std::optional<ProgramTree> ProgramTree::Build (
216
+ const parser::BlockData &x, SemanticsContext &context) {
191
217
const auto &stmt{std::get<parser::Statement<parser::BlockDataStmt>>(x.t )};
192
218
const auto &end{std::get<parser::Statement<parser::EndBlockDataStmt>>(x.t )};
193
219
static parser::Name emptyName;
194
- auto result{stmt.statement .v ? BuildSubprogramTree (*stmt.statement .v , x)
195
- : BuildSubprogramTree (emptyName, x)};
196
- return result.set_stmt (stmt).set_endStmt (end);
220
+ auto result{stmt.statement .v
221
+ ? BuildSubprogramTree (*stmt.statement .v , context, x)
222
+ : BuildSubprogramTree (emptyName, context, x)};
223
+ return std::move (result.set_stmt (stmt).set_endStmt (end));
197
224
}
198
225
199
- ProgramTree ProgramTree::Build (const parser::CompilerDirective &) {
200
- DIE (" ProgramTree::Build() called for CompilerDirective" );
226
+ std::optional<ProgramTree> ProgramTree::Build (
227
+ const parser::CompilerDirective &x, SemanticsContext &context) {
228
+ context.Say (x.source , " Compiler directive ignored here" _warn_en_US);
229
+ return std::nullopt;
201
230
}
202
231
203
- ProgramTree ProgramTree::Build (const parser::OpenACCRoutineConstruct &) {
232
+ std::optional<ProgramTree> ProgramTree::Build (
233
+ const parser::OpenACCRoutineConstruct &, SemanticsContext &) {
204
234
DIE (" ProgramTree::Build() called for OpenACCRoutineConstruct" );
205
235
}
206
236
0 commit comments