[lldb] Add ability to hide the root name of a value
[llvm-project.git] / flang / lib / Semantics / check-purity.cpp
blob5176390f366bd51481272aa4a9f10ca91fc296d1
1 //===-- lib/Semantics/check-purity.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 //===----------------------------------------------------------------------===//
9 #include "check-purity.h"
10 #include "flang/Parser/parse-tree.h"
11 #include "flang/Semantics/tools.h"
13 namespace Fortran::semantics {
14 void PurityChecker::Enter(const parser::ExecutableConstruct &exec) {
15 if (InPureSubprogram() && IsImageControlStmt(exec)) {
16 context_.Say(GetImageControlStmtLocation(exec),
17 "An image control statement may not appear in a pure subprogram"_err_en_US);
20 void PurityChecker::Enter(const parser::SubroutineSubprogram &subr) {
21 const auto &stmt{std::get<parser::Statement<parser::SubroutineStmt>>(subr.t)};
22 Entered(
23 stmt.source, std::get<std::list<parser::PrefixSpec>>(stmt.statement.t));
26 void PurityChecker::Leave(const parser::SubroutineSubprogram &) { Left(); }
28 void PurityChecker::Enter(const parser::FunctionSubprogram &func) {
29 const auto &stmt{std::get<parser::Statement<parser::FunctionStmt>>(func.t)};
30 Entered(
31 stmt.source, std::get<std::list<parser::PrefixSpec>>(stmt.statement.t));
34 void PurityChecker::Leave(const parser::FunctionSubprogram &) { Left(); }
36 bool PurityChecker::InPureSubprogram() const {
37 return pureDepth_ >= 0 && depth_ >= pureDepth_;
40 bool PurityChecker::HasPurePrefix(
41 const std::list<parser::PrefixSpec> &prefixes) const {
42 for (const parser::PrefixSpec &prefix : prefixes) {
43 if (std::holds_alternative<parser::PrefixSpec::Pure>(prefix.u)) {
44 return true;
47 return false;
50 void PurityChecker::Entered(
51 parser::CharBlock source, const std::list<parser::PrefixSpec> &prefixes) {
52 if (depth_ == 2) {
53 context_.messages().Say(source,
54 "An internal subprogram may not contain an internal subprogram"_err_en_US);
56 if (HasPurePrefix(prefixes)) {
57 if (pureDepth_ < 0) {
58 pureDepth_ = depth_;
60 } else if (InPureSubprogram()) {
61 context_.messages().Say(source,
62 "An internal subprogram of a pure subprogram must also be pure"_err_en_US);
64 ++depth_;
67 void PurityChecker::Left() {
68 if (pureDepth_ == --depth_) {
69 pureDepth_ = -1;
73 } // namespace Fortran::semantics