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 "flang/Optimizer/Builder/Todo.h"
15#include "mlir/IR/BuiltinTypes.h"
16#include "llvm/Support/Debug.h"
17#include <optional>
18
19#define DEBUG_TYPE "flang-lower-symbol-map"
20
21void Fortran::lower::SymMap::addSymbol(Fortran::semantics::SymbolRef sym,
22 const fir::ExtendedValue &exv,
23 bool force) {
24 exv.match([&](const fir::UnboxedValue &v) { addSymbol(sym, v, force); },
25 [&](const fir::CharBoxValue &v) { makeSym(sym, v, force); },
26 [&](const fir::ArrayBoxValue &v) { makeSym(sym, v, force); },
27 [&](const fir::CharArrayBoxValue &v) { makeSym(sym, v, force); },
28 [&](const fir::BoxValue &v) { makeSym(sym, v, force); },
29 [&](const fir::MutableBoxValue &v) { makeSym(sym, v, force); },
30 [&](const fir::PolymorphicValue &v) { makeSym(sym, v, force); },
31 [](auto) {
32 llvm::report_fatal_error("value not added to symbol table");
33 });
34}
35
36Fortran::lower::SymbolBox
37Fortran::lower::SymMap::lookupSymbol(Fortran::semantics::SymbolRef symRef) {
38 auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();
39 for (auto jmap = symbolMapStack.rbegin(), jend = symbolMapStack.rend();
40 jmap != jend; ++jmap) {
41 auto iter = jmap->find(sym);
42 if (iter != jmap->end())
43 return iter->second;
44 }
45 return SymbolBox::None{};
46}
47
48Fortran::lower::SymbolBox Fortran::lower::SymMap::shallowLookupSymbol(
49 Fortran::semantics::SymbolRef symRef) {
50 auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();
51 auto &map = symbolMapStack.back();
52 auto iter = map.find(sym);
53 if (iter != map.end())
54 return iter->second;
55 return SymbolBox::None{};
56}
57
58/// Skip one level when looking up the symbol. The use case is such as looking
59/// up the host variable symbol box by skipping the associated level in
60/// host-association in OpenMP code.
61Fortran::lower::SymbolBox Fortran::lower::SymMap::lookupOneLevelUpSymbol(
62 Fortran::semantics::SymbolRef symRef) {
63 auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();
64 auto jmap = symbolMapStack.rbegin();
65 auto jend = symbolMapStack.rend();
66 if (jmap == jend)
67 return SymbolBox::None{};
68 // Skip one level in symbol map stack.
69 for (++jmap; jmap != jend; ++jmap) {
70 auto iter = jmap->find(sym);
71 if (iter != jmap->end())
72 return iter->second;
73 }
74 return SymbolBox::None{};
75}
76
77mlir::Value
78Fortran::lower::SymMap::lookupImpliedDo(Fortran::lower::SymMap::AcDoVar var) {
79 for (auto [marker, binding] : llvm::reverse(impliedDoStack))
80 if (var == marker)
81 return binding;
82 return {};
83}
84
85llvm::raw_ostream &
86Fortran::lower::operator<<(llvm::raw_ostream &os,
87 const Fortran::lower::SymbolBox &symBox) {
88 symBox.match(
89 [&](const Fortran::lower::SymbolBox::None &box) {
90 os << "** symbol not properly mapped **\n";
91 },
92 [&](const Fortran::lower::SymbolBox::Intrinsic &val) {
93 os << val.getAddr() << '\n';
94 },
95 [&](const auto &box) { os << box << '\n'; });
96 return os;
97}
98
99llvm::raw_ostream &
100Fortran::lower::operator<<(llvm::raw_ostream &os,
101 const Fortran::lower::SymMap &symMap) {
102 os << "Symbol map:\n";
103 for (auto i : llvm::enumerate(symMap.symbolMapStack)) {
104 os << " level " << i.index() << "<{\n";
105 for (auto iter : i.value()) {
106 os << " symbol @" << static_cast<const void *>(iter.first) << " ["
107 << *iter.first << "] ->\n ";
108 os << iter.second;
109 }
110 os << " }>\n";
111 }
112 return os;
113}
114

source code of flang/lib/Lower/SymbolMap.cpp