//===-- SymbolMap.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Pretty printers for symbol boxes, etc.
//
//===----------------------------------------------------------------------===//
#include "flang/Lower/SymbolMap.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "mlir/IR/BuiltinTypes.h"
#include "llvm/Support/Debug.h"
#include <optional>
#define DEBUG_TYPE "flang-lower-symbol-map"
void Fortran::lower::SymMap::addSymbol(Fortran::semantics::SymbolRef sym,
const fir::ExtendedValue &exv,
bool force) {
exv.match([&](const fir::UnboxedValue &v) { addSymbol(sym, v, force); },
[&](const fir::CharBoxValue &v) { makeSym(sym, v, force); },
[&](const fir::ArrayBoxValue &v) { makeSym(sym, v, force); },
[&](const fir::CharArrayBoxValue &v) { makeSym(sym, v, force); },
[&](const fir::BoxValue &v) { makeSym(sym, v, force); },
[&](const fir::MutableBoxValue &v) { makeSym(sym, v, force); },
[&](const fir::PolymorphicValue &v) { makeSym(sym, v, force); },
[](auto) {
llvm::report_fatal_error("value not added to symbol table");
});
}
Fortran::lower::SymbolBox
Fortran::lower::SymMap::lookupSymbol(Fortran::semantics::SymbolRef symRef) {
auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();
for (auto jmap = symbolMapStack.rbegin(), jend = symbolMapStack.rend();
jmap != jend; ++jmap) {
auto iter = jmap->find(sym);
if (iter != jmap->end())
return iter->second;
}
return SymbolBox::None{};
}
Fortran::lower::SymbolBox Fortran::lower::SymMap::shallowLookupSymbol(
Fortran::semantics::SymbolRef symRef) {
auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();
auto &map = symbolMapStack.back();
auto iter = map.find(sym);
if (iter != map.end())
return iter->second;
return SymbolBox::None{};
}
/// Skip one level when looking up the symbol. The use case is such as looking
/// up the host variable symbol box by skipping the associated level in
/// host-association in OpenMP code.
Fortran::lower::SymbolBox Fortran::lower::SymMap::lookupOneLevelUpSymbol(
Fortran::semantics::SymbolRef symRef) {
auto *sym = symRef->HasLocalLocality() ? &*symRef : &symRef->GetUltimate();
auto jmap = symbolMapStack.rbegin();
auto jend = symbolMapStack.rend();
if (jmap == jend)
return SymbolBox::None{};
// Skip one level in symbol map stack.
for (++jmap; jmap != jend; ++jmap) {
auto iter = jmap->find(sym);
if (iter != jmap->end())
return iter->second;
}
return SymbolBox::None{};
}
mlir::Value
Fortran::lower::SymMap::lookupImpliedDo(Fortran::lower::SymMap::AcDoVar var) {
for (auto [marker, binding] : llvm::reverse(impliedDoStack))
if (var == marker)
return binding;
return {};
}
llvm::raw_ostream &
Fortran::lower::operator<<(llvm::raw_ostream &os,
const Fortran::lower::SymbolBox &symBox) {
symBox.match(
[&](const Fortran::lower::SymbolBox::None &box) {
os << "** symbol not properly mapped **\n";
},
[&](const Fortran::lower::SymbolBox::Intrinsic &val) {
os << val.getAddr() << '\n';
},
[&](const auto &box) { os << box << '\n'; });
return os;
}
llvm::raw_ostream &
Fortran::lower::operator<<(llvm::raw_ostream &os,
const Fortran::lower::SymMap &symMap) {
os << "Symbol map:\n";
for (auto i : llvm::enumerate(symMap.symbolMapStack)) {
os << " level " << i.index() << "<{\n";
for (auto iter : i.value()) {
os << " symbol @" << static_cast<const void *>(iter.first) << " ["
<< *iter.first << "] ->\n ";
os << iter.second;
}
os << " }>\n";
}
return os;
}