aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2020-12-10 17:44:33 +0000
committerPhilip Herron <herron.philip@googlemail.com>2020-12-17 17:23:46 +0000
commit3514168b990fd67225c59e84c7fffec075788905 (patch)
tree937dc0fbfe0a754e502f1947a01fdb4e20ad5698
parent29fb9e4d937f2d98734330f46f539514e2518cc3 (diff)
downloadgcc-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.in3
-rw-r--r--gcc/rust/util/rust-hir-map.cc312
-rw-r--r--gcc/rust/util/rust-hir-map.h134
-rw-r--r--gcc/rust/util/rust-inference-var.h112
-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