// Copyright (C) 2020 Free Software Foundation, Inc.
// This file is part of GCC.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3, or (at your option) any later
// version.
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
// You should have received a copy of the GNU General Public License
// along with GCC; see the file COPYING3. If not see
// .
#include "rust-hir-map.h"
#include "rust-ast-full.h"
#include "rust-hir-full.h"
namespace Rust {
namespace Analysis {
NodeMapping::NodeMapping (CrateNum crateNum, NodeId nodeId, HirId hirId,
LocalDefId localDefId)
: crateNum (crateNum), nodeId (nodeId), hirId (hirId), localDefId (localDefId)
{}
NodeMapping::~NodeMapping () {}
NodeMapping
NodeMapping::get_error ()
{
return NodeMapping (UNKNOWN_CREATENUM, UNKNOWN_NODEID, UNKNOWN_HIRID,
UNKNOWN_LOCAL_DEFID);
}
CrateNum
NodeMapping::get_crate_num () const
{
return crateNum;
}
NodeId
NodeMapping::get_nodeid () const
{
return nodeId;
}
HirId
NodeMapping::get_hirid () const
{
return hirId;
}
LocalDefId
NodeMapping::get_local_defid () const
{
return localDefId;
}
DefId
NodeMapping::get_defid () const
{
return get_defid (get_crate_num (), get_local_defid ());
}
DefId
NodeMapping::get_defid (CrateNum crate_num, LocalDefId local_defid)
{
return ((uint64_t) crate_num << 32) | local_defid;
}
std::string
NodeMapping::as_string () const
{
std::ostringstream ss;
ss << "["
<< "C: " << get_crate_num ();
if (get_nodeid () != UNKNOWN_NODEID)
ss << " Nid: " << get_nodeid ();
if (get_hirid () != UNKNOWN_HIRID)
ss << " Hid: " << get_hirid ();
if (get_local_defid () != UNKNOWN_LOCAL_DEFID)
ss << " Lid: " << get_local_defid ();
ss << "]";
return ss.str ();
}
// Mappings Class now
Mappings::Mappings () {}
Mappings::~Mappings () {}
Mappings *
Mappings::get ()
{
static std::unique_ptr instance;
if (!instance)
instance = std::unique_ptr (new Mappings ());
return instance.get ();
}
CrateNum
Mappings::get_next_crate_num ()
{
return crateNumItr++;
}
void
Mappings::set_current_crate (CrateNum crateNum)
{
currentCrateNum = crateNum;
}
CrateNum
Mappings::setup_crate_mappings (std::string crate_name)
{
CrateNum crate_num = get_next_crate_num ();
hirIdIter[crate_num] = UNKNOWN_HIRID;
nodeIdIter[crate_num] = UNKNOWN_NODEID;
localIdIter[crate_num] = UNKNOWN_LOCAL_DEFID;
nodeIdToHirMappings[crate_num] = {};
locations[crate_num] = {};
crate_names[crate_num] = crate_name;
return crate_num;
}
CrateNum
Mappings::get_current_crate () const
{
return currentCrateNum;
}
NodeId
Mappings::get_next_node_id (CrateNum crateNum)
{
auto it = nodeIdIter.find (crateNum);
rust_assert (it != nodeIdIter.end ());
auto id = it->second + 1;
nodeIdIter[crateNum] = id;
return id;
}
HirId
Mappings::get_next_hir_id (CrateNum crateNum)
{
auto it = hirIdIter.find (crateNum);
rust_assert (it != hirIdIter.end ());
auto id = it->second + 1;
hirIdIter[crateNum] = id;
hirNodesWithinCrate[crateNum].insert (id);
return id;
}
LocalDefId
Mappings::get_next_localdef_id (CrateNum crateNum)
{
auto it = localIdIter.find (crateNum);
rust_assert (it != localIdIter.end ());
auto id = it->second + 1;
localIdIter[crateNum] = id;
return id;
}
AST::Crate *
Mappings::get_ast_crate (CrateNum crateNum)
{
auto it = astCrateMappings.find (crateNum);
if (it == astCrateMappings.end ())
return nullptr;
return it->second;
}
void
Mappings::insert_ast_crate (AST::Crate *crate)
{
CrateNum crateNum = get_current_crate ();
rust_assert (get_ast_crate (crateNum) == nullptr);
astCrateMappings[crateNum] = crate;
}
HIR::Crate *
Mappings::get_hir_crate (CrateNum crateNum)
{
auto it = hirCrateMappings.find (crateNum);
if (it == hirCrateMappings.end ())
return nullptr;
return it->second;
}
void
Mappings::insert_hir_crate (HIR::Crate *crate)
{
CrateNum crateNum = crate->get_mappings ().get_crate_num ();
rust_assert (get_hir_crate (crateNum) == nullptr);
hirCrateMappings[crateNum] = crate;
}
void
Mappings::insert_defid_mapping (DefId id, HIR::Item *item)
{
CrateNum crate_num = (id & DEF_ID_CRATE_MASK) >> 32;
LocalDefId local_def_id = id & DEF_ID_LOCAL_DEF_MASK;
rust_assert (lookup_defid (id) == nullptr);
rust_assert (lookup_local_defid (crate_num, local_def_id) == nullptr);
defIdMappings[id] = item;
insert_local_defid_mapping (crate_num, local_def_id, item);
}
HIR::Item *
Mappings::lookup_defid (DefId id)
{
auto it = defIdMappings.find (id);
if (it == defIdMappings.end ())
return nullptr;
return it->second;
}
void
Mappings::insert_hir_item (CrateNum crateNum, HirId id, HIR::Item *item)
{
rust_assert (lookup_hir_item (crateNum, id) == nullptr);
hirItemMappings[crateNum][id] = item;
nodeIdToHirMappings[crateNum][item->get_mappings ().get_nodeid ()] = id;
}
HIR::Item *
Mappings::lookup_hir_item (CrateNum crateNum, HirId id)
{
auto it = hirItemMappings.find (crateNum);
if (it == hirItemMappings.end ())
return nullptr;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return nullptr;
return iy->second;
}
void
Mappings::insert_hir_trait_item (CrateNum crateNum, HirId id,
HIR::TraitItem *item)
{
rust_assert (lookup_hir_trait_item (crateNum, id) == nullptr);
hirTraitItemMappings[crateNum][id] = item;
nodeIdToHirMappings[crateNum][item->get_mappings ().get_nodeid ()] = id;
}
HIR::TraitItem *
Mappings::lookup_hir_trait_item (CrateNum crateNum, HirId id)
{
auto it = hirTraitItemMappings.find (crateNum);
if (it == hirTraitItemMappings.end ())
return nullptr;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return nullptr;
return iy->second;
}
void
Mappings::insert_hir_extern_item (CrateNum crateNum, HirId id,
HIR::ExternalItem *item)
{
rust_assert (lookup_hir_extern_item (crateNum, id) == nullptr);
hirExternItemMappings[crateNum][id] = item;
nodeIdToHirMappings[crateNum][item->get_mappings ().get_nodeid ()] = id;
}
HIR::ExternalItem *
Mappings::lookup_hir_extern_item (CrateNum crateNum, HirId id)
{
auto it = hirExternItemMappings.find (crateNum);
if (it == hirExternItemMappings.end ())
return nullptr;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return nullptr;
return iy->second;
}
void
Mappings::insert_hir_impl_block (CrateNum crateNum, HirId id,
HIR::ImplBlock *item)
{
rust_assert (lookup_hir_impl_block (crateNum, id) == nullptr);
hirImplBlockMappings[crateNum][id] = item;
nodeIdToHirMappings[crateNum][item->get_mappings ().get_nodeid ()] = id;
}
HIR::ImplBlock *
Mappings::lookup_hir_impl_block (CrateNum crateNum, HirId id)
{
auto it = hirImplBlockMappings.find (crateNum);
if (it == hirImplBlockMappings.end ())
return nullptr;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return nullptr;
return iy->second;
}
void
Mappings::insert_hir_implitem (CrateNum crateNum, HirId id,
HirId parent_impl_id, HIR::ImplItem *item)
{
rust_assert (lookup_hir_implitem (crateNum, id, nullptr) == nullptr);
hirImplItemMappings[crateNum][id]
= std::pair (parent_impl_id, item);
nodeIdToHirMappings[crateNum][item->get_impl_mappings ().get_nodeid ()] = id;
}
HIR::ImplItem *
Mappings::lookup_hir_implitem (CrateNum crateNum, HirId id,
HirId *parent_impl_id)
{
auto it = hirImplItemMappings.find (crateNum);
if (it == hirImplItemMappings.end ())
return nullptr;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return nullptr;
std::pair &ref = iy->second;
if (parent_impl_id != nullptr)
*parent_impl_id = ref.first;
return ref.second;
}
void
Mappings::insert_hir_expr (CrateNum crateNum, HirId id, HIR::Expr *expr)
{
hirExprMappings[crateNum][id] = expr;
nodeIdToHirMappings[crateNum][expr->get_mappings ().get_nodeid ()] = id;
insert_location (crateNum, id, expr->get_locus_slow ());
}
HIR::Expr *
Mappings::lookup_hir_expr (CrateNum crateNum, HirId id)
{
auto it = hirExprMappings.find (crateNum);
if (it == hirExprMappings.end ())
return nullptr;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return nullptr;
return iy->second;
}
void
Mappings::insert_hir_path_expr_seg (CrateNum crateNum, HirId id,
HIR::PathExprSegment *expr)
{
rust_assert (lookup_hir_path_expr_seg (crateNum, id) == nullptr);
hirPathSegMappings[crateNum][id] = expr;
nodeIdToHirMappings[crateNum][expr->get_mappings ().get_nodeid ()] = id;
insert_location (crateNum, id, expr->get_locus ());
}
HIR::PathExprSegment *
Mappings::lookup_hir_path_expr_seg (CrateNum crateNum, HirId id)
{
auto it = hirPathSegMappings.find (crateNum);
if (it == hirPathSegMappings.end ())
return nullptr;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return nullptr;
return iy->second;
}
void
Mappings::insert_hir_generic_param (CrateNum crateNum, HirId id,
HIR::GenericParam *param)
{
rust_assert (lookup_hir_generic_param (crateNum, id) == nullptr);
hirGenericParamMappings[crateNum][id] = param;
nodeIdToHirMappings[crateNum][param->get_mappings ().get_nodeid ()] = id;
insert_location (crateNum, id, param->get_locus_slow ());
}
HIR::GenericParam *
Mappings::lookup_hir_generic_param (CrateNum crateNum, HirId id)
{
auto it = hirGenericParamMappings.find (crateNum);
if (it == hirGenericParamMappings.end ())
return nullptr;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return nullptr;
return iy->second;
}
void
Mappings::insert_hir_type (CrateNum crateNum, HirId id, HIR::Type *type)
{
rust_assert (lookup_hir_type (crateNum, id) == nullptr);
hirTypeMappings[crateNum][id] = type;
nodeIdToHirMappings[crateNum][type->get_mappings ().get_nodeid ()] = id;
}
HIR::Type *
Mappings::lookup_hir_type (CrateNum crateNum, HirId id)
{
auto it = hirTypeMappings.find (crateNum);
if (it == hirTypeMappings.end ())
return nullptr;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return nullptr;
return iy->second;
}
void
Mappings::insert_hir_stmt (CrateNum crateNum, HirId id, HIR::Stmt *type)
{
rust_assert (lookup_hir_stmt (crateNum, id) == nullptr);
hirStmtMappings[crateNum][id] = type;
nodeIdToHirMappings[crateNum][type->get_mappings ().get_nodeid ()] = id;
}
HIR::Stmt *
Mappings::lookup_hir_stmt (CrateNum crateNum, HirId id)
{
auto it = hirStmtMappings.find (crateNum);
if (it == hirStmtMappings.end ())
return nullptr;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return nullptr;
return iy->second;
}
void
Mappings::insert_hir_param (CrateNum crateNum, HirId id,
HIR::FunctionParam *param)
{
rust_assert (lookup_hir_stmt (crateNum, id) == nullptr);
hirParamMappings[crateNum][id] = param;
nodeIdToHirMappings[crateNum][param->get_mappings ().get_nodeid ()] = id;
}
HIR::FunctionParam *
Mappings::lookup_hir_param (CrateNum crateNum, HirId id)
{
auto it = hirParamMappings.find (crateNum);
if (it == hirParamMappings.end ())
return nullptr;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return nullptr;
return iy->second;
}
void
Mappings::insert_hir_self_param (CrateNum crateNum, HirId id,
HIR::SelfParam *param)
{
rust_assert (lookup_hir_stmt (crateNum, id) == nullptr);
hirSelfParamMappings[crateNum][id] = param;
nodeIdToHirMappings[crateNum][param->get_mappings ().get_nodeid ()] = id;
}
HIR::SelfParam *
Mappings::lookup_hir_self_param (CrateNum crateNum, HirId id)
{
auto it = hirSelfParamMappings.find (crateNum);
if (it == hirSelfParamMappings.end ())
return nullptr;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return nullptr;
return iy->second;
}
void
Mappings::insert_hir_struct_field (CrateNum crateNum, HirId id,
HIR::StructExprField *field)
{
rust_assert (lookup_hir_stmt (crateNum, id) == nullptr);
hirStructFieldMappings[crateNum][id] = field;
nodeIdToHirMappings[crateNum][field->get_mappings ().get_nodeid ()] = id;
}
HIR::StructExprField *
Mappings::lookup_hir_struct_field (CrateNum crateNum, HirId id)
{
auto it = hirStructFieldMappings.find (crateNum);
if (it == hirStructFieldMappings.end ())
return nullptr;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return nullptr;
return iy->second;
}
void
Mappings::insert_local_defid_mapping (CrateNum crateNum, LocalDefId id,
HIR::Item *item)
{
rust_assert (lookup_local_defid (crateNum, id) == nullptr);
localDefIdMappings[crateNum][id] = item;
}
HIR::Item *
Mappings::lookup_local_defid (CrateNum crateNum, LocalDefId id)
{
auto it = localDefIdMappings.find (crateNum);
if (it == localDefIdMappings.end ())
return nullptr;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return nullptr;
return iy->second;
}
void
Mappings::walk_local_defids_for_crate (CrateNum crateNum,
std::function cb)
{
auto it = localDefIdMappings.find (crateNum);
if (it == localDefIdMappings.end ())
return;
for (auto iy = it->second.begin (); iy != it->second.end (); iy++)
{
if (!cb (iy->second))
return;
}
}
void
Mappings::insert_node_to_hir (CrateNum crate, NodeId id, HirId ref)
{
nodeIdToHirMappings[crate][id] = ref;
}
bool
Mappings::lookup_node_to_hir (CrateNum crate, NodeId id, HirId *ref)
{
auto it = nodeIdToHirMappings.find (crate);
if (it == nodeIdToHirMappings.end ())
return false;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return false;
*ref = iy->second;
return true;
}
void
Mappings::insert_location (CrateNum crate, HirId id, Location locus)
{
locations[crate][id] = locus;
}
Location
Mappings::lookup_location (CrateNum crate, HirId id)
{
auto it = locations.find (crate);
if (it == locations.end ())
return Location ();
auto iy = it->second.find (id);
if (iy == it->second.end ())
return Location ();
return iy->second;
}
bool
Mappings::resolve_nodeid_to_stmt (CrateNum crate, NodeId id, HIR::Stmt **stmt)
{
auto it = nodeIdToHirMappings.find (crate);
if (it == nodeIdToHirMappings.end ())
return false;
auto iy = it->second.find (id);
if (iy == it->second.end ())
return false;
HirId resolved = iy->second;
auto resolved_stmt = lookup_hir_stmt (crate, resolved);
*stmt = resolved_stmt;
return resolved_stmt != nullptr;
}
void
Mappings::iterate_impl_items (
std::function cb)
{
for (auto it = hirImplItemMappings.begin (); it != hirImplItemMappings.end ();
it++)
{
for (auto iy = it->second.begin (); iy != it->second.end (); iy++)
{
auto id = iy->first;
auto impl_item = iy->second.second;
auto impl = lookup_associated_impl (
impl_item->get_impl_mappings ().get_hirid ());
if (!cb (id, impl_item, impl))
return;
}
}
}
void
Mappings::iterate_impl_blocks (std::function cb)
{
for (auto it = hirImplBlockMappings.begin ();
it != hirImplBlockMappings.end (); it++)
{
for (auto iy = it->second.begin (); iy != it->second.end (); iy++)
{
HirId id = iy->first;
HIR::ImplBlock *impl_block = iy->second;
if (!cb (id, impl_block))
return;
}
}
}
} // namespace Analysis
} // namespace Rust