1 //===-- SymbolMap.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 // Pretty printers for symbol boxes, etc.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "flang/Lower/SymbolMap.h"
14 #include "mlir/IR/BuiltinTypes.h"
15 #include "llvm/Support/Debug.h"
16 
17 #define DEBUG_TYPE "flang-lower-symbol-map"
18 
19 void Fortran::lower::SymMap::addSymbol(Fortran::semantics::SymbolRef sym,
20                                        const fir::ExtendedValue &exv,
21                                        bool force) {
22   exv.match([&](const fir::UnboxedValue &v) { addSymbol(sym, v, force); },
23             [&](const fir::CharBoxValue &v) { makeSym(sym, v, force); },
24             [&](const fir::ArrayBoxValue &v) { makeSym(sym, v, force); },
25             [&](const fir::CharArrayBoxValue &v) { makeSym(sym, v, force); },
26             [&](const fir::BoxValue &v) { makeSym(sym, v, force); },
27             [&](const fir::MutableBoxValue &v) { makeSym(sym, v, force); },
28             [](auto) {
29               llvm::report_fatal_error("value not added to symbol table");
30             });
31 }
32 
33 Fortran::lower::SymbolBox
34 Fortran::lower::SymMap::lookupSymbol(Fortran::semantics::SymbolRef symRef) {
35   Fortran::semantics::SymbolRef sym = symRef.get().GetUltimate();
36   for (auto jmap = symbolMapStack.rbegin(), jend = symbolMapStack.rend();
37        jmap != jend; ++jmap) {
38     auto iter = jmap->find(&*sym);
39     if (iter != jmap->end())
40       return iter->second;
41   }
42   return SymbolBox::None{};
43 }
44 
45 Fortran::lower::SymbolBox Fortran::lower::SymMap::shallowLookupSymbol(
46     Fortran::semantics::SymbolRef symRef) {
47   auto &map = symbolMapStack.back();
48   auto iter = map.find(&symRef.get().GetUltimate());
49   if (iter != map.end())
50     return iter->second;
51   return SymbolBox::None{};
52 }
53 
54 mlir::Value
55 Fortran::lower::SymMap::lookupImpliedDo(Fortran::lower::SymMap::AcDoVar var) {
56   for (auto [marker, binding] : llvm::reverse(impliedDoStack))
57     if (var == marker)
58       return binding;
59   return {};
60 }
61 
62 llvm::raw_ostream &
63 Fortran::lower::operator<<(llvm::raw_ostream &os,
64                            const Fortran::lower::SymbolBox &symBox) {
65   symBox.match(
66       [&](const Fortran::lower::SymbolBox::None &box) {
67         os << "** symbol not properly mapped **\n";
68       },
69       [&](const Fortran::lower::SymbolBox::Intrinsic &val) {
70         os << val.getAddr() << '\n';
71       },
72       [&](const auto &box) { os << box << '\n'; });
73   return os;
74 }
75 
76 llvm::raw_ostream &
77 Fortran::lower::operator<<(llvm::raw_ostream &os,
78                            const Fortran::lower::SymMap &symMap) {
79   os << "Symbol map:\n";
80   for (auto i : llvm::enumerate(symMap.symbolMapStack)) {
81     os << " level " << i.index() << "<{\n";
82     for (auto iter : i.value())
83       os << "  symbol @" << static_cast<const void *>(iter.first) << " ["
84          << *iter.first << "] ->\n    " << iter.second;
85     os << " }>\n";
86   }
87   return os;
88 }
89