xref: /llvm-project/flang/lib/Evaluate/common.cpp (revision 0f973ac783aa100cfbce1cd2c6e8a3a8f648fae7)
1 //===-- lib/Evaluate/common.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/Evaluate/common.h"
10 #include "flang/Common/idioms.h"
11 
12 using namespace Fortran::parser::literals;
13 
14 namespace Fortran::evaluate {
15 
16 void RealFlagWarnings(
17     FoldingContext &context, const RealFlags &flags, const char *operation) {
18   static constexpr auto warning{common::UsageWarning::FoldingException};
19   if (context.languageFeatures().ShouldWarn(warning)) {
20     if (flags.test(RealFlag::Overflow)) {
21       context.messages().Say(warning, "overflow on %s"_warn_en_US, operation);
22     }
23     if (flags.test(RealFlag::DivideByZero)) {
24       if (std::strcmp(operation, "division") == 0) {
25         context.messages().Say(warning, "division by zero"_warn_en_US);
26       } else {
27         context.messages().Say(
28             warning, "division by zero on %s"_warn_en_US, operation);
29       }
30     }
31     if (flags.test(RealFlag::InvalidArgument)) {
32       context.messages().Say(
33           warning, "invalid argument on %s"_warn_en_US, operation);
34     }
35     if (flags.test(RealFlag::Underflow)) {
36       context.messages().Say(warning, "underflow on %s"_warn_en_US, operation);
37     }
38   }
39 }
40 
41 ConstantSubscript &FoldingContext::StartImpliedDo(
42     parser::CharBlock name, ConstantSubscript n) {
43   auto pair{impliedDos_.insert(std::make_pair(name, n))};
44   CHECK(pair.second);
45   return pair.first->second;
46 }
47 
48 std::optional<ConstantSubscript> FoldingContext::GetImpliedDo(
49     parser::CharBlock name) const {
50   if (auto iter{impliedDos_.find(name)}; iter != impliedDos_.cend()) {
51     return {iter->second};
52   } else {
53     return std::nullopt;
54   }
55 }
56 
57 void FoldingContext::EndImpliedDo(parser::CharBlock name) {
58   auto iter{impliedDos_.find(name)};
59   if (iter != impliedDos_.end()) {
60     impliedDos_.erase(iter);
61   }
62 }
63 } // namespace Fortran::evaluate
64