diff options
author | Philip Herron <philip.herron@embecosm.com> | 2020-12-10 17:44:33 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2020-12-17 17:23:46 +0000 |
commit | 3514168b990fd67225c59e84c7fffec075788905 (patch) | |
tree | 937dc0fbfe0a754e502f1947a01fdb4e20ad5698 | |
parent | 29fb9e4d937f2d98734330f46f539514e2518cc3 (diff) | |
download | gcc-3514168b990fd67225c59e84c7fffec075788905.zip gcc-3514168b990fd67225c59e84c7fffec075788905.tar.gz gcc-3514168b990fd67225c59e84c7fffec075788905.tar.bz2 |
Introduce HIR Mapping
This is the start of a bigger refactor of the compiler to follow the
rustc internals. This introduces a mapping system for.
- HirId which maps to any Hir Node within the current crate
- LocalDefId any toplevel Hir Node HIR::Item within current crate
- NodeId maps any AST node akin to HirId such that they can map back
- DefId Cratea and localDefId combination
-rw-r--r-- | gcc/rust/Make-lang.in | 3 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.cc | 312 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.h | 134 | ||||
-rw-r--r-- | gcc/rust/util/rust-inference-var.h | 112 | ||||
-rw-r--r-- | gcc/rust/util/scope.h (renamed from gcc/rust/analysis/scope.h) | 23 |
5 files changed, 582 insertions, 2 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index 234d51b..7159725 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -74,6 +74,7 @@ GRS_OBJS = \ rust/rust-scan.o \ rust/rust-compile.o \ rust/rust-macro-expand.o \ + rust/rust-hir-map.o \ $(END) # removed object files from here @@ -217,7 +218,7 @@ CFLAGS-rust/rust-lang.o += -DDEFAULT_TARGET_VERSION=\"$(version)\" \ -DDEFAULT_TARGET_MACHINE=\"$(target_noncanonical)\" # cross-folder includes - add new folders later -RUST_INCLUDES = -I $(srcdir)/rust -I $(srcdir)/rust/lex -I $(srcdir)/rust/parse -I $(srcdir)/rust/ast -I $(srcdir)/rust/analysis -I $(srcdir)/rust/backend -I $(srcdir)/rust/expand +RUST_INCLUDES = -I $(srcdir)/rust -I $(srcdir)/rust/lex -I $(srcdir)/rust/parse -I $(srcdir)/rust/ast -I $(srcdir)/rust/analysis -I $(srcdir)/rust/backend -I $(srcdir)/rust/expand -I $(srcdir)/rust/util # add files that require cross-folder includes - currently rust-lang.o, rust-lex.o CFLAGS-rust/rust-lang.o += $(RUST_INCLUDES) diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc new file mode 100644 index 0000000..ff3e548 --- /dev/null +++ b/gcc/rust/util/rust-hir-map.cc @@ -0,0 +1,312 @@ +// 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 +// <http://www.gnu.org/licenses/>. + +#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 +{ + DefId val = 0; + val |= get_crate_num (); + val = val << sizeof (uint32_t); + val |= get_local_defid (); + return val; +} + +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<Mappings> instance; + if (!instance) + instance = std::move (std::unique_ptr<Mappings> (new Mappings ())); + + return instance.get (); +} + +CrateNum +Mappings::get_next_crate_num () +{ + return crateNumItr++; +} + +void +Mappings::set_current_crate (CrateNum crateNum) +{ + currentCrateNum = crateNum; +} + +CrateNum +Mappings::get_current_crate () +{ + // HACK + if (hirIdIter.find (currentCrateNum) == hirIdIter.end ()) + { + hirIdIter[currentCrateNum] = UNKNOWN_HIRID; + nodeIdIter[currentCrateNum] = UNKNOWN_NODEID; + localIdIter[currentCrateNum] = UNKNOWN_LOCAL_DEFID; + } + + 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; + 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 crateNum = (id & DEF_ID_CRATE_MASK) >> sizeof (uint32_t); + LocalDefId localDefId = id & DEF_ID_LOCAL_DEF_MASK; + + rust_assert (lookup_defid (id) == nullptr); + rust_assert (lookup_local_defid (crateNum, localDefId) == nullptr); + + defIdMappings[id] = item; + insert_local_defid_mapping (crateNum, localDefId, 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; +} + +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_expr (CrateNum crateNum, HirId id, HIR::Expr *expr) +{ + rust_assert (lookup_hir_expr (crateNum, id) == nullptr); + + hirExprMappings[crateNum][id] = expr; +} + +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_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<bool (HIR::Item *)> 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; + } +} + +} // namespace Analysis +} // namespace Rust diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h new file mode 100644 index 0000000..cbe22a5 --- /dev/null +++ b/gcc/rust/util/rust-hir-map.h @@ -0,0 +1,134 @@ +// 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_MAP_H +#define RUST_HIR_MAP_H + +#include "rust-system.h" + +#include "rust-ast-full-decls.h" +#include "rust-hir-full-decls.h" + +namespace Rust { + +// refers to a Crate +typedef uint32_t CrateNum; +// refers to any node in the AST in current Crate +typedef uint32_t NodeId; +// refers to any node in the HIR for the current crate +typedef uint32_t HirId; +// refers to any top-level decl in HIR +typedef uint32_t LocalDefId; +// refers to <Crate><DefId> +typedef uint64_t DefId; + +#define DEF_ID_CRATE_MASK 0xFFFFFFFF00000000 +#define DEF_ID_LOCAL_DEF_MASK 0x00000000FFFFFFFF + +#define UNKNOWN_CREATENUM ((uint32_t) (-1)) +#define UNKNOWN_NODEID ((uint32_t) (-1)) +#define UNKNOWN_HIRID ((uint32_t) (-1)) +#define UNKNOWN_LOCAL_DEFID ((uint32_t) (-1)) +#define UNKNOWN_DEFID ((uint64_t) (-1)) + +namespace Analysis { + +class NodeMapping +{ +public: + NodeMapping (CrateNum crateNum, NodeId nodeId, HirId hirId, + LocalDefId localDefId); + ~NodeMapping (); + + static NodeMapping get_error (); + + CrateNum get_crate_num () const; + NodeId get_nodeid () const; + HirId get_hirid () const; + LocalDefId get_local_defid () const; + DefId get_defid () const; + + std::string as_string () const; + +private: + CrateNum crateNum; + NodeId nodeId; + HirId hirId; + LocalDefId localDefId; +}; + +class Mappings +{ +public: + static Mappings *get (); + ~Mappings (); + + CrateNum get_next_crate_num (); + void set_current_crate (CrateNum crateNum); + CrateNum get_current_crate (); + + NodeId get_next_node_id () { return get_next_node_id (get_current_crate ()); } + NodeId get_next_node_id (CrateNum crateNum); + HirId get_next_hir_id (CrateNum crateNum); + LocalDefId get_next_localdef_id (CrateNum crateNum); + + AST::Crate *get_ast_crate (CrateNum crateNum); + void insert_ast_crate (AST::Crate *crate); + + HIR::Crate *get_hir_crate (CrateNum crateNum); + void insert_hir_crate (HIR::Crate *crate); + + void insert_defid_mapping (DefId id, HIR::Item *item); + HIR::Item *lookup_defid (DefId id); + + void insert_local_defid_mapping (CrateNum crateNum, LocalDefId id, + HIR::Item *item); + HIR::Item *lookup_local_defid (CrateNum crateNum, LocalDefId id); + + void insert_hir_item (CrateNum crateNum, HirId id, HIR::Item *item); + HIR::Item *lookup_hir_item (CrateNum crateNum, HirId id); + + void insert_hir_expr (CrateNum crateNum, HirId id, HIR::Expr *expr); + HIR::Expr *lookup_hir_expr (CrateNum crateNum, HirId id); + + void walk_local_defids_for_crate (CrateNum crateNum, + std::function<bool (HIR::Item *)> cb); + +private: + Mappings (); + + CrateNum crateNumItr; + CrateNum currentCrateNum; + + std::map<CrateNum, HirId> hirIdIter; + std::map<CrateNum, NodeId> nodeIdIter; + std::map<CrateNum, LocalDefId> localIdIter; + + std::map<CrateNum, AST::Crate *> astCrateMappings; + std::map<CrateNum, HIR::Crate *> hirCrateMappings; + + std::map<DefId, HIR::Item *> defIdMappings; + std::map<CrateNum, std::map<LocalDefId, HIR::Item *> > localDefIdMappings; + std::map<CrateNum, std::map<HirId, HIR::Item *> > hirItemMappings; + std::map<CrateNum, std::map<HirId, HIR::Expr *> > hirExprMappings; +}; + +} // namespace Analysis +} // namespace Rust + +#endif // RUST_HIR_MAP_H diff --git a/gcc/rust/util/rust-inference-var.h b/gcc/rust/util/rust-inference-var.h new file mode 100644 index 0000000..87decd5 --- /dev/null +++ b/gcc/rust/util/rust-inference-var.h @@ -0,0 +1,112 @@ +// 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_INFERENCE_VAR +#define RUST_HIR_INFERENCE_VAR + +#include "rust-system.h" +#include "rust-hir-full-decls.h" + +namespace Rust { +namespace HIR { + +class GeneralInferenceVariable; +class IntegralInferenceVariable; +class FloatInferenceVariable; +class InferenceVarVisitor +{ +public: + virtual void visit (GeneralInferenceVariable &v) {} + virtual void visit (IntegralInferenceVariable &v) {} + virtual void visit (FloatInferenceVariable &v) {} +}; + +// Base +class InferenceVariable +{ +public: + virtual ~InferenceVariable () {} + + virtual std::string as_string () const = 0; + + HIR::Type *get_type () { return resolved; } + + void set_type (HIR::Type *type) { resolved = type; } + + bool was_resolved () { return resolved != nullptr; } + + virtual void accept_vis (InferenceVarVisitor &vis) = 0; + +protected: + InferenceVariable () : resolved (nullptr) {} + + HIR::Type *resolved; +}; + +class GeneralInferenceVariable : public InferenceVariable +{ +public: + GeneralInferenceVariable () : InferenceVariable () {} + + void accept_vis (InferenceVarVisitor &vis) { vis.visit (*this); }; + + std::string as_string () const override + { + if (resolved) + return resolved->as_string (); + + return "[G::?T]"; + } +}; + +class IntegralInferenceVariable : public InferenceVariable +{ +public: + IntegralInferenceVariable () : InferenceVariable () {} + + void accept_vis (InferenceVarVisitor &vis) { vis.visit (*this); }; + + std::string as_string () const override + { + if (resolved) + return resolved->as_string (); + + return "[I::?T]"; + } +}; + +class FloatInferenceVariable : public InferenceVariable +{ +public: + FloatInferenceVariable () : InferenceVariable () {} + + void accept_vis (InferenceVarVisitor &vis) { vis.visit (*this); }; + + std::string as_string () const override + { + if (resolved) + return resolved->as_string (); + + return "[F::?T]"; + } +}; + +} // namespace HIR +} // namespace Rust + +#endif // RUST_HIR_INFERENCE_VAR diff --git a/gcc/rust/analysis/scope.h b/gcc/rust/util/scope.h index 41bcee6..6e853c3 100644 --- a/gcc/rust/analysis/scope.h +++ b/gcc/rust/util/scope.h @@ -1,4 +1,23 @@ -#pragma once +// 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_SCOPE_H +#define RUST_SCOPE_H #include "rust-system.h" #include "rust-ast-full.h" @@ -55,3 +74,5 @@ private: } // namespace Analysis } // namespace Rust + +#endif // RUST_SCOPE_H |