aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2020-12-10 20:02:03 +0000
committerPhilip Herron <herron.philip@googlemail.com>2020-12-17 17:23:46 +0000
commit4fb0ab7e635c65318aadf958e0e1303f3435c4e5 (patch)
treeb1472ad8c7c1d23686231a1bf0a697db4c2aef92 /gcc
parent2cfc6276dadc54aea9f8ce2a8cfefaee456f380e (diff)
downloadgcc-4fb0ab7e635c65318aadf958e0e1303f3435c4e5.zip
gcc-4fb0ab7e635c65318aadf958e0e1303f3435c4e5.tar.gz
gcc-4fb0ab7e635c65318aadf958e0e1303f3435c4e5.tar.bz2
This sets up a name resolution framework trying to follow rust-dev guide
We can use the NodeId from the AST to generate apropriate mappings for all names and types. Ribs are the scopes for names being instansiated, and reference to defintion tables allows all names to be resolved to NodeId's. Later on NodeIds will map over to HIR ids allowing for type resolution.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in7
-rw-r--r--gcc/rust/ast/rust-ast.h111
-rw-r--r--gcc/rust/ast/rust-expr.h5
-rw-r--r--gcc/rust/ast/rust-path.h10
-rw-r--r--gcc/rust/ast/rust-pattern.h12
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h18
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.h16
-rw-r--r--gcc/rust/hir/rust-ast-lower-pattern.h6
-rw-r--r--gcc/rust/hir/rust-ast-lower-stmt.h8
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.h258
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h98
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h68
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.h97
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.h59
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-toplevel.h54
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h66
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc245
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.h50
-rw-r--r--gcc/rust/resolve/rust-name-resolver.h211
-rw-r--r--gcc/rust/rust-session-manager.cc31
-rw-r--r--gcc/rust/rust-session-manager.h29
-rw-r--r--gcc/rust/util/rust-hir-map.cc10
-rw-r--r--gcc/rust/util/rust-hir-map.h5
23 files changed, 1329 insertions, 145 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index b9b2345..aa81813 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -77,6 +77,7 @@ GRS_OBJS = \
rust/rust-hir-full-test.o \
rust/rust-hir-map.o \
rust/rust-ast-lower.o \
+ rust/rust-ast-resolve.o \
$(END)
# removed object files from here
@@ -229,7 +230,7 @@ RUST_INCLUDES = -I $(srcdir)/rust \
-I $(srcdir)/rust/expand \
-I $(srcdir)/rust/hir/tree \
-I $(srcdir)/rust/hir \
- -I $(srcdir)/rust/hir_resolve \
+ -I $(srcdir)/rust/resolve \
-I $(srcdir)/rust/util
# add files that require cross-folder includes - currently rust-lang.o, rust-lex.o
@@ -286,4 +287,8 @@ rust/%.o: rust/hir/tree/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
$(POSTCOMPILE)
+# build rust/hir/tree files in rust folder
+rust/%.o: rust/resolve/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index fe60ae0..b26c770 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -266,91 +266,6 @@ public:
bool is_error () const { return value_as_string == ""; }
};
-// A token tree with delimiters
-class DelimTokenTree : public TokenTree, public AttrInput
-{
- DelimType delim_type;
- std::vector<std::unique_ptr<TokenTree> > token_trees;
- Location locus;
-
-protected:
- DelimTokenTree *clone_delim_tok_tree_impl () const
- {
- return new DelimTokenTree (*this);
- }
-
- /* Use covariance to implement clone function as returning a DelimTokenTree
- * object */
- DelimTokenTree *clone_attr_input_impl () const override
- {
- return clone_delim_tok_tree_impl ();
- }
-
- /* Use covariance to implement clone function as returning a DelimTokenTree
- * object */
- DelimTokenTree *clone_token_tree_impl () const override
- {
- return clone_delim_tok_tree_impl ();
- }
-
-public:
- DelimTokenTree (DelimType delim_type,
- std::vector<std::unique_ptr<TokenTree> > token_trees
- = std::vector<std::unique_ptr<TokenTree> > (),
- Location locus = Location ())
- : delim_type (delim_type), token_trees (std::move (token_trees)),
- locus (locus)
- {}
-
- // Copy constructor with vector clone
- DelimTokenTree (DelimTokenTree const &other)
- : delim_type (other.delim_type), locus (other.locus)
- {
- token_trees.reserve (other.token_trees.size ());
- for (const auto &e : other.token_trees)
- token_trees.push_back (e->clone_token_tree ());
- }
-
- // overloaded assignment operator with vector clone
- DelimTokenTree &operator= (DelimTokenTree const &other)
- {
- delim_type = other.delim_type;
- locus = other.locus;
-
- token_trees.reserve (other.token_trees.size ());
- for (const auto &e : other.token_trees)
- token_trees.push_back (e->clone_token_tree ());
-
- return *this;
- }
-
- // move constructors
- DelimTokenTree (DelimTokenTree &&other) = default;
- DelimTokenTree &operator= (DelimTokenTree &&other) = default;
-
- static DelimTokenTree create_empty () { return DelimTokenTree (PARENS); }
-
- std::string as_string () const override;
-
- void accept_vis (ASTVisitor &vis) override;
-
- bool
- check_cfg_predicate (const Session &session ATTRIBUTE_UNUSED) const override
- {
- // this should never be called - should be converted first
- return false;
- }
-
- AttrInput *parse_to_meta_item () const override;
-
- std::vector<std::unique_ptr<Token> > to_token_stream () const override;
-
- std::unique_ptr<DelimTokenTree> clone_delim_token_tree () const
- {
- return std::unique_ptr<DelimTokenTree> (clone_delim_tok_tree_impl ());
- }
-};
-
/* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr to
* be defined */
class AttrInputLiteral;
@@ -955,7 +870,7 @@ public:
virtual void mark_for_strip () = 0;
virtual bool is_marked_for_strip () const = 0;
- NodeId get_node_id () const { return node_id; }
+ virtual NodeId get_node_id () const { return node_id; }
protected:
// Constructor
@@ -1090,9 +1005,15 @@ public:
* methods. */
virtual Location get_locus_slow () const = 0;
+ virtual NodeId get_node_id () const { return node_id; }
+
protected:
// Clone pattern implementation as pure virtual method
virtual Pattern *clone_pattern_impl () const = 0;
+
+ Pattern () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
+
+ NodeId node_id;
};
// forward decl for Type
@@ -1127,9 +1048,15 @@ public:
virtual Location get_locus_slow () const = 0;
+ NodeId get_node_id () const { return node_id; }
+
protected:
+ Type () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
+
// Clone function implementation as pure virtual method
virtual Type *clone_type_impl () const = 0;
+
+ NodeId node_id;
};
// A type without parentheses? - abstract
@@ -1153,6 +1080,8 @@ protected:
{
return clone_type_no_bounds_impl ();
}
+
+ TypeNoBounds () : Type () {}
};
/* Abstract base class representing a type param bound - Lifetime and TraitBound
@@ -1572,19 +1501,22 @@ struct Crate
* top-level one)? */
std::vector<std::unique_ptr<Item> > items;
+ NodeId node_id;
+
public:
// Constructor
Crate (std::vector<std::unique_ptr<Item> > items,
std::vector<Attribute> inner_attrs, bool has_utf8bom = false,
bool has_shebang = false)
: has_utf8bom (has_utf8bom), has_shebang (has_shebang),
- inner_attrs (std::move (inner_attrs)), items (std::move (items))
+ inner_attrs (std::move (inner_attrs)), items (std::move (items)),
+ node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
// Copy constructor with vector clone
Crate (Crate const &other)
: has_utf8bom (other.has_utf8bom), has_shebang (other.has_shebang),
- inner_attrs (other.inner_attrs)
+ inner_attrs (other.inner_attrs), node_id (other.node_id)
{
items.reserve (other.items.size ());
for (const auto &e : other.items)
@@ -1599,6 +1531,7 @@ public:
inner_attrs = other.inner_attrs;
has_shebang = other.has_shebang;
has_utf8bom = other.has_utf8bom;
+ node_id = other.node_id;
items.reserve (other.items.size ());
for (const auto &e : other.items)
@@ -1624,6 +1557,8 @@ public:
items.shrink_to_fit ();
// TODO: is this the best way to do this?
}
+
+ NodeId get_node_id () const { return node_id; }
};
// Base path expression AST node - abstract
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 864ee1d..de011c1 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -2338,11 +2338,6 @@ public:
}
}
-protected:
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- CallExpr *clone_expr_impl () const override { return new CallExpr (*this); }
-
// TODO: this mutable getter seems really dodgy. Think up better way.
const std::vector<std::unique_ptr<Expr> > &get_params () const
{
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 20138b6..bd3b0f0 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -296,6 +296,8 @@ class PathInExpression : public PathPattern, public PathExpr
bool has_opening_scope_resolution;
Location locus;
+ NodeId _node_id;
+
public:
std::string as_string () const override;
@@ -307,7 +309,8 @@ public:
= std::vector<Attribute> ())
: PathPattern (std::move (path_segments)),
PathExpr (std::move (outer_attrs)),
- has_opening_scope_resolution (has_opening_scope_resolution), locus (locus)
+ has_opening_scope_resolution (has_opening_scope_resolution),
+ locus (locus), _node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
// Creates an error state path in expression.
@@ -341,6 +344,8 @@ public:
bool is_marked_for_strip () const override { return is_error (); }
bool opening_scope_resolution () { return has_opening_scope_resolution; }
+ NodeId get_node_id () const override { return _node_id; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -654,7 +659,8 @@ public:
// Constructor
TypePath (std::vector<std::unique_ptr<TypePathSegment> > segments,
Location locus, bool has_opening_scope_resolution = false)
- : has_opening_scope_resolution (has_opening_scope_resolution),
+ : TypeNoBounds (),
+ has_opening_scope_resolution (has_opening_scope_resolution),
segments (std::move (segments)), locus (locus)
{}
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 3a87a83..dc4d48c 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -69,8 +69,8 @@ public:
IdentifierPattern (Identifier ident, Location locus, bool is_ref = false,
bool is_mut = false,
std::unique_ptr<Pattern> to_bind = nullptr)
- : variable_ident (std::move (ident)), is_ref (is_ref), is_mut (is_mut),
- to_bind (std::move (to_bind)), locus (locus)
+ : Pattern (), variable_ident (std::move (ident)), is_ref (is_ref),
+ is_mut (is_mut), to_bind (std::move (to_bind)), locus (locus)
{}
// Copy constructor with clone
@@ -78,7 +78,9 @@ public:
: variable_ident (other.variable_ident), is_ref (other.is_ref),
is_mut (other.is_mut), locus (other.locus)
{
- // fix to prevent null pointer dereference
+ node_id = other.node_id;
+ // fix to get prevent null pointer dereference
+
if (other.to_bind != nullptr)
to_bind = other.to_bind->clone_pattern ();
}
@@ -90,6 +92,7 @@ public:
is_ref = other.is_ref;
is_mut = other.is_mut;
locus = other.locus;
+ node_id = other.node_id;
// fix to prevent null pointer dereference
if (other.to_bind != nullptr)
@@ -118,6 +121,9 @@ public:
Identifier get_ident () const { return variable_ident; }
+ bool get_is_mut () const { return is_mut; }
+ bool get_is_ref () const { return is_ref; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index 6454a78..50e67a8 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -70,9 +70,10 @@ public:
void visit (AST::ReturnExpr &expr)
{
- HIR::Expr *return_expr = expr.has_return_expr ()
- ? ASTLoweringExpr::translate (expr.get_expr ())
- : nullptr;
+ HIR::Expr *return_expr
+ = expr.has_returned_expr ()
+ ? ASTLoweringExpr::translate (expr.get_returned_expr ().get ())
+ : nullptr;
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
@@ -86,7 +87,8 @@ public:
void visit (AST::CallExpr &expr)
{
std::vector<HIR::Attribute> outer_attribs;
- HIR::Expr *func = ASTLoweringExpr::translate (expr.function.get ());
+ HIR::Expr *func
+ = ASTLoweringExpr::translate (expr.get_function_expr ().get ());
std::vector<std::unique_ptr<HIR::Expr> > params;
expr.iterate_params ([&] (AST::Expr *p) mutable -> bool {
auto trans = ASTLoweringExpr::translate (p);
@@ -107,8 +109,8 @@ public:
void visit (AST::AssignmentExpr &expr)
{
- HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_lhs ());
- HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_rhs ());
+ HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ().get ());
+ HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ().get ());
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
@@ -211,9 +213,9 @@ public:
break;
}
- HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_lhs ());
+ HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ().get ());
rust_assert (lhs != nullptr);
- HIR::Expr *rhs = ASTLoweringExpr::translate (expr.right_expr.get ());
+ HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_right_expr ().get ());
rust_assert (rhs != nullptr);
auto crate_num = mappings->get_current_crate ();
diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h
index 5983e88..71e465e 100644
--- a/gcc/rust/hir/rust-ast-lower-item.h
+++ b/gcc/rust/hir/rust-ast-lower-item.h
@@ -53,21 +53,21 @@ public:
HIR::Visibility vis = HIR::Visibility::create_public ();
// need
- Identifier function_name = function.function_name;
+ Identifier function_name = function.get_function_name ();
Location locus = function.get_locus ();
std::unique_ptr<HIR::Type> return_type
- = function.has_function_return_type () ? std::unique_ptr<HIR::Type> (
- ASTLoweringType::translate (function.return_type.get ()))
- : nullptr;
+ = function.has_return_type () ? std::unique_ptr<HIR::Type> (
+ ASTLoweringType::translate (function.get_return_type ().get ()))
+ : nullptr;
std::vector<HIR::FunctionParam> function_params;
- for (auto &param : function.function_params)
+ for (auto &param : function.get_function_params ())
{
auto translated_pattern = std::unique_ptr<HIR::Pattern> (
- ASTLoweringPattern::translate (param.param_name.get ()));
+ ASTLoweringPattern::translate (param.get_pattern ().get ()));
auto translated_type = std::unique_ptr<HIR::Type> (
- ASTLoweringType::translate (param.type.get ()));
+ ASTLoweringType::translate (param.get_type ().get ()));
function_params.push_back (
HIR::FunctionParam (std::move (translated_pattern),
@@ -76,7 +76,7 @@ public:
std::unique_ptr<HIR::BlockExpr> function_body
= std::unique_ptr<HIR::BlockExpr> (
- translate (function.function_body.get ()));
+ translate (function.get_definition ().get ()));
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, function.get_node_id (),
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.h b/gcc/rust/hir/rust-ast-lower-pattern.h
index b69c9d9..0d5ce0f 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.h
+++ b/gcc/rust/hir/rust-ast-lower-pattern.h
@@ -41,9 +41,9 @@ public:
{
std::unique_ptr<Pattern> to_bind;
translated
- = new HIR::IdentifierPattern (pattern.variable_ident,
- pattern.get_locus (), pattern.is_ref,
- pattern.is_mut, std::move (to_bind));
+ = new HIR::IdentifierPattern (pattern.get_ident (), pattern.get_locus (),
+ pattern.get_is_ref (),
+ pattern.get_is_mut (), std::move (to_bind));
}
private:
diff --git a/gcc/rust/hir/rust-ast-lower-stmt.h b/gcc/rust/hir/rust-ast-lower-stmt.h
index d21b49d..d18dc19 100644
--- a/gcc/rust/hir/rust-ast-lower-stmt.h
+++ b/gcc/rust/hir/rust-ast-lower-stmt.h
@@ -48,7 +48,7 @@ public:
void visit (AST::ExprStmtWithoutBlock &stmt)
{
- HIR::Expr *expr = ASTLoweringExpr::translate (stmt.expr.get ());
+ HIR::Expr *expr = ASTLoweringExpr::translate (stmt.get_expr ().get ());
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, stmt.get_node_id (),
@@ -64,13 +64,13 @@ public:
{
std::vector<HIR::Attribute> outer_attrs;
HIR::Pattern *variables
- = ASTLoweringPattern::translate (stmt.variables_pattern.get ());
+ = ASTLoweringPattern::translate (stmt.get_pattern ().get ());
HIR::Type *type = stmt.has_type ()
- ? ASTLoweringType::translate (stmt.type.get ())
+ ? ASTLoweringType::translate (stmt.get_type ().get ())
: nullptr;
HIR::Expr *init_expression
= stmt.has_init_expr ()
- ? ASTLoweringExpr::translate (stmt.init_expr.get ())
+ ? ASTLoweringExpr::translate (stmt.get_init_expr ().get ())
: nullptr;
auto crate_num = mappings->get_current_crate ();
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h
new file mode 100644
index 0000000..cc60055
--- /dev/null
+++ b/gcc/rust/resolve/rust-ast-resolve-base.h
@@ -0,0 +1,258 @@
+// 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_AST_RESOLVE_BASE_H
+#define RUST_AST_RESOLVE_BASE_H
+
+#include "rust-ast-visitor.h"
+#include "rust-name-resolver.h"
+
+#include "rust-diagnostics.h"
+#include "rust-location.h"
+
+namespace Rust {
+namespace Resolver {
+
+class ResolverBase : public AST::ASTVisitor
+{
+public:
+ virtual ~ResolverBase () {}
+
+ // visitor impl
+ // rust-ast.h
+ // virtual void visit(AttrInput& attr_input);
+ // virtual void visit(TokenTree& token_tree);
+ // virtual void visit(MacroMatch& macro_match);
+ virtual void visit (AST::Token &tok) {}
+ virtual void visit (AST::DelimTokenTree &delim_tok_tree) {}
+ virtual void visit (AST::AttrInputMetaItemContainer &input) {}
+ // virtual void visit(MetaItem& meta_item) {}
+ // void vsit(Stmt& stmt) {}
+ // virtual void visit(Expr& expr) {}
+ virtual void visit (AST::IdentifierExpr &ident_expr) {}
+ // virtual void visit(Pattern& pattern) {}
+ // virtual void visit(Type& type) {}
+ // virtual void visit(TypeParamBound& type_param_bound) {}
+ virtual void visit (AST::Lifetime &lifetime) {}
+ // virtual void visit(GenericParam& generic_param) {}
+ virtual void visit (AST::LifetimeParam &lifetime_param) {}
+ // virtual void visit(TraitItem& trait_item) {}
+ // virtual void visit(InherentImplItem& inherent_impl_item) {}
+ // virtual void visit(TraitImplItem& trait_impl_item) {}
+ virtual void visit (AST::MacroInvocationSemi &macro) {}
+
+ // rust-path.h
+ virtual void visit (AST::PathInExpression &path) {}
+ virtual void visit (AST::TypePathSegment &segment) {}
+ virtual void visit (AST::TypePathSegmentGeneric &segment) {}
+ virtual void visit (AST::TypePathSegmentFunction &segment) {}
+ virtual void visit (AST::TypePath &path) {}
+ virtual void visit (AST::QualifiedPathInExpression &path) {}
+ virtual void visit (AST::QualifiedPathInType &path) {}
+
+ // rust-expr.h
+ virtual void visit (AST::LiteralExpr &expr) {}
+ virtual void visit (AST::AttrInputLiteral &attr_input) {}
+ virtual void visit (AST::MetaItemLitExpr &meta_item) {}
+ virtual void visit (AST::MetaItemPathLit &meta_item) {}
+ virtual void visit (AST::BorrowExpr &expr) {}
+ virtual void visit (AST::DereferenceExpr &expr) {}
+ virtual void visit (AST::ErrorPropagationExpr &expr) {}
+ virtual void visit (AST::NegationExpr &expr) {}
+ virtual void visit (AST::ArithmeticOrLogicalExpr &expr) {}
+ virtual void visit (AST::ComparisonExpr &expr) {}
+ virtual void visit (AST::LazyBooleanExpr &expr) {}
+ virtual void visit (AST::TypeCastExpr &expr) {}
+ virtual void visit (AST::AssignmentExpr &expr) {}
+ virtual void visit (AST::CompoundAssignmentExpr &expr) {}
+ virtual void visit (AST::GroupedExpr &expr) {}
+ // virtual void visit(ArrayElems& elems) {}
+ virtual void visit (AST::ArrayElemsValues &elems) {}
+ virtual void visit (AST::ArrayElemsCopied &elems) {}
+ virtual void visit (AST::ArrayExpr &expr) {}
+ virtual void visit (AST::ArrayIndexExpr &expr) {}
+ virtual void visit (AST::TupleExpr &expr) {}
+ virtual void visit (AST::TupleIndexExpr &expr) {}
+ virtual void visit (AST::StructExprStruct &expr) {}
+ // virtual void visit(StructExprField& field) {}
+ virtual void visit (AST::StructExprFieldIdentifier &field) {}
+ virtual void visit (AST::StructExprFieldIdentifierValue &field) {}
+ virtual void visit (AST::StructExprFieldIndexValue &field) {}
+ virtual void visit (AST::StructExprStructFields &expr) {}
+ virtual void visit (AST::StructExprStructBase &expr) {}
+ virtual void visit (AST::StructExprTuple &expr) {}
+ virtual void visit (AST::StructExprUnit &expr) {}
+ // virtual void visit(EnumExprField& field) {}
+ virtual void visit (AST::EnumExprFieldIdentifier &field) {}
+ virtual void visit (AST::EnumExprFieldIdentifierValue &field) {}
+ virtual void visit (AST::EnumExprFieldIndexValue &field) {}
+ virtual void visit (AST::EnumExprStruct &expr) {}
+ virtual void visit (AST::EnumExprTuple &expr) {}
+ virtual void visit (AST::EnumExprFieldless &expr) {}
+ virtual void visit (AST::CallExpr &expr) {}
+ virtual void visit (AST::MethodCallExpr &expr) {}
+ virtual void visit (AST::FieldAccessExpr &expr) {}
+ virtual void visit (AST::ClosureExprInner &expr) {}
+ virtual void visit (AST::BlockExpr &expr) {}
+ virtual void visit (AST::ClosureExprInnerTyped &expr) {}
+ virtual void visit (AST::ContinueExpr &expr) {}
+ virtual void visit (AST::BreakExpr &expr) {}
+ virtual void visit (AST::RangeFromToExpr &expr) {}
+ virtual void visit (AST::RangeFromExpr &expr) {}
+ virtual void visit (AST::RangeToExpr &expr) {}
+ virtual void visit (AST::RangeFullExpr &expr) {}
+ virtual void visit (AST::RangeFromToInclExpr &expr) {}
+ virtual void visit (AST::RangeToInclExpr &expr) {}
+ virtual void visit (AST::ReturnExpr &expr) {}
+ virtual void visit (AST::UnsafeBlockExpr &expr) {}
+ virtual void visit (AST::LoopExpr &expr) {}
+ virtual void visit (AST::WhileLoopExpr &expr) {}
+ virtual void visit (AST::WhileLetLoopExpr &expr) {}
+ virtual void visit (AST::ForLoopExpr &expr) {}
+ virtual void visit (AST::IfExpr &expr) {}
+ virtual void visit (AST::IfExprConseqElse &expr) {}
+ virtual void visit (AST::IfExprConseqIf &expr) {}
+ virtual void visit (AST::IfExprConseqIfLet &expr) {}
+ virtual void visit (AST::IfLetExpr &expr) {}
+ virtual void visit (AST::IfLetExprConseqElse &expr) {}
+ virtual void visit (AST::IfLetExprConseqIf &expr) {}
+ virtual void visit (AST::IfLetExprConseqIfLet &expr) {}
+ // virtual void visit(MatchCase& match_case) {}
+ // virtual void visit (AST::MatchCaseBlockExpr &match_case) {}
+ // virtual void visit (AST::MatchCaseExpr &match_case) {}
+ virtual void visit (AST::MatchExpr &expr) {}
+ virtual void visit (AST::AwaitExpr &expr) {}
+ virtual void visit (AST::AsyncBlockExpr &expr) {}
+
+ // rust-item.h
+ virtual void visit (AST::TypeParam &param) {}
+ // virtual void visit(WhereClauseItem& item) {}
+ virtual void visit (AST::LifetimeWhereClauseItem &item) {}
+ virtual void visit (AST::TypeBoundWhereClauseItem &item) {}
+ virtual void visit (AST::Method &method) {}
+ virtual void visit (AST::ModuleBodied &module) {}
+ virtual void visit (AST::ModuleNoBody &module) {}
+ virtual void visit (AST::ExternCrate &crate) {}
+ // virtual void visit(UseTree& use_tree) {}
+ virtual void visit (AST::UseTreeGlob &use_tree) {}
+ virtual void visit (AST::UseTreeList &use_tree) {}
+ virtual void visit (AST::UseTreeRebind &use_tree) {}
+ virtual void visit (AST::UseDeclaration &use_decl) {}
+ virtual void visit (AST::Function &function) {}
+ virtual void visit (AST::TypeAlias &type_alias) {}
+ virtual void visit (AST::StructStruct &struct_item) {}
+ virtual void visit (AST::TupleStruct &tuple_struct) {}
+ virtual void visit (AST::EnumItem &item) {}
+ virtual void visit (AST::EnumItemTuple &item) {}
+ virtual void visit (AST::EnumItemStruct &item) {}
+ virtual void visit (AST::EnumItemDiscriminant &item) {}
+ virtual void visit (AST::Enum &enum_item) {}
+ virtual void visit (AST::Union &union_item) {}
+ virtual void visit (AST::ConstantItem &const_item) {}
+ virtual void visit (AST::StaticItem &static_item) {}
+ virtual void visit (AST::TraitItemFunc &item) {}
+ virtual void visit (AST::TraitItemMethod &item) {}
+ virtual void visit (AST::TraitItemConst &item) {}
+ virtual void visit (AST::TraitItemType &item) {}
+ virtual void visit (AST::Trait &trait) {}
+ virtual void visit (AST::InherentImpl &impl) {}
+ virtual void visit (AST::TraitImpl &impl) {}
+ // virtual void visit(ExternalItem& item) {}
+ virtual void visit (AST::ExternalStaticItem &item) {}
+ virtual void visit (AST::ExternalFunctionItem &item) {}
+ virtual void visit (AST::ExternBlock &block) {}
+
+ // rust-macro.h
+ virtual void visit (AST::MacroMatchFragment &match) {}
+ virtual void visit (AST::MacroMatchRepetition &match) {}
+ virtual void visit (AST::MacroMatcher &matcher) {}
+ virtual void visit (AST::MacroRulesDefinition &rules_def) {}
+ virtual void visit (AST::MacroInvocation &macro_invoc) {}
+ virtual void visit (AST::MetaItemPath &meta_item) {}
+ virtual void visit (AST::MetaItemSeq &meta_item) {}
+ virtual void visit (AST::MetaWord &meta_item) {}
+ virtual void visit (AST::MetaNameValueStr &meta_item) {}
+ virtual void visit (AST::MetaListPaths &meta_item) {}
+ virtual void visit (AST::MetaListNameValueStr &meta_item) {}
+
+ // rust-pattern.h
+ virtual void visit (AST::LiteralPattern &pattern) {}
+ virtual void visit (AST::IdentifierPattern &pattern) {}
+ virtual void visit (AST::WildcardPattern &pattern) {}
+ // virtual void visit(RangePatternBound& bound) {}
+ virtual void visit (AST::RangePatternBoundLiteral &bound) {}
+ virtual void visit (AST::RangePatternBoundPath &bound) {}
+ virtual void visit (AST::RangePatternBoundQualPath &bound) {}
+ virtual void visit (AST::RangePattern &pattern) {}
+ virtual void visit (AST::ReferencePattern &pattern) {}
+ // virtual void visit(StructPatternField& field) {}
+ virtual void visit (AST::StructPatternFieldTuplePat &field) {}
+ virtual void visit (AST::StructPatternFieldIdentPat &field) {}
+ virtual void visit (AST::StructPatternFieldIdent &field) {}
+ virtual void visit (AST::StructPattern &pattern) {}
+ // virtual void visit(TupleStructItems& tuple_items) {}
+ virtual void visit (AST::TupleStructItemsNoRange &tuple_items) {}
+ virtual void visit (AST::TupleStructItemsRange &tuple_items) {}
+ virtual void visit (AST::TupleStructPattern &pattern) {}
+ // virtual void visit(TuplePatternItems& tuple_items) {}
+ virtual void visit (AST::TuplePatternItemsMultiple &tuple_items) {}
+ virtual void visit (AST::TuplePatternItemsRanged &tuple_items) {}
+ virtual void visit (AST::TuplePattern &pattern) {}
+ virtual void visit (AST::GroupedPattern &pattern) {}
+ virtual void visit (AST::SlicePattern &pattern) {}
+
+ // rust-stmt.h
+ virtual void visit (AST::EmptyStmt &stmt) {}
+ virtual void visit (AST::LetStmt &stmt) {}
+ virtual void visit (AST::ExprStmtWithoutBlock &stmt) {}
+ virtual void visit (AST::ExprStmtWithBlock &stmt) {}
+
+ // rust-type.h
+ virtual void visit (AST::TraitBound &bound) {}
+ virtual void visit (AST::ImplTraitType &type) {}
+ virtual void visit (AST::TraitObjectType &type) {}
+ virtual void visit (AST::ParenthesisedType &type) {}
+ virtual void visit (AST::ImplTraitTypeOneBound &type) {}
+ virtual void visit (AST::TraitObjectTypeOneBound &type) {}
+ virtual void visit (AST::TupleType &type) {}
+ virtual void visit (AST::NeverType &type) {}
+ virtual void visit (AST::RawPointerType &type) {}
+ virtual void visit (AST::ReferenceType &type) {}
+ virtual void visit (AST::ArrayType &type) {}
+ virtual void visit (AST::SliceType &type) {}
+ virtual void visit (AST::InferredType &type) {}
+ virtual void visit (AST::BareFunctionType &type) {}
+
+protected:
+ ResolverBase (NodeId parent)
+ : resolver (Resolver::get ()), resolved_node (UNKNOWN_NODEID),
+ parent (parent), locus (Location ())
+ {}
+
+ bool resolved () const { return resolved_node != UNKNOWN_NODEID; }
+
+ Resolver *resolver;
+ NodeId resolved_node;
+ NodeId parent;
+ Location locus;
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_AST_RESOLVE_BASE_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
new file mode 100644
index 0000000..9ca763d
--- /dev/null
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -0,0 +1,98 @@
+// 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_AST_RESOLVE_EXPR_H
+#define RUST_AST_RESOLVE_EXPR_H
+
+#include "rust-ast-resolve-base.h"
+#include "rust-ast-full.h"
+
+namespace Rust {
+namespace Resolver {
+
+class ResolveExpr : public ResolverBase
+{
+public:
+ static void go (AST::Expr *expr, NodeId parent)
+ {
+ ResolveExpr resolver (parent);
+ expr->accept_vis (resolver);
+ };
+
+ ~ResolveExpr () {}
+
+ void visit (AST::PathInExpression &expr)
+ {
+ if (resolver->get_name_scope ().lookup (expr.as_string (), &resolved_node))
+ {
+ resolver->insert_resolved_name (expr.get_node_id (), resolved_node);
+ resolver->insert_new_definition (expr.get_node_id (),
+ Definition{expr.get_node_id (),
+ parent});
+ }
+ }
+
+ void visit (AST::ReturnExpr &expr)
+ {
+ if (expr.has_return_expr ())
+ ResolveExpr::go (expr.get_expr (), expr.get_node_id ());
+ }
+
+ void visit (AST::CallExpr &expr)
+ {
+ ResolveExpr::go (expr.function.get (), expr.get_node_id ());
+ expr.iterate_params ([&] (AST::Expr *p) mutable -> bool {
+ ResolveExpr::go (p, expr.get_node_id ());
+ return true;
+ });
+ }
+
+ void visit (AST::AssignmentExpr &expr)
+ {
+ ResolveExpr::go (expr.get_lhs (), expr.get_node_id ());
+ ResolveExpr::go (expr.get_rhs (), expr.get_node_id ());
+ }
+
+ void visit (AST::IdentifierExpr &expr)
+ {
+ if (!resolver->get_name_scope ().lookup (expr.as_string (), &resolved_node))
+ {
+ rust_error_at (expr.get_locus (), "failed to find name: %s",
+ expr.as_string ().c_str ());
+ return;
+ }
+
+ resolver->insert_resolved_name (expr.get_node_id (), resolved_node);
+ resolver->insert_new_definition (expr.get_node_id (),
+ Definition{expr.get_node_id (), parent});
+ }
+
+ void visit (AST::ArithmeticOrLogicalExpr &expr)
+ {
+ ResolveExpr::go (expr.get_lhs (), expr.get_node_id ());
+ ResolveExpr::go (expr.right_expr.get (), expr.get_node_id ());
+ }
+
+private:
+ ResolveExpr (NodeId parent) : ResolverBase (parent) {}
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_AST_RESOLVE_EXPR_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
new file mode 100644
index 0000000..ea79fc0
--- /dev/null
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -0,0 +1,68 @@
+// 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_AST_RESOLVE_ITEM_H
+#define RUST_AST_RESOLVE_ITEM_H
+
+#include "rust-ast-resolve-base.h"
+#include "rust-ast-full.h"
+#include "rust-ast-resolve-type.h"
+#include "rust-ast-resolve-pattern.h"
+
+namespace Rust {
+namespace Resolver {
+
+class ResolveItem : public ResolverBase
+{
+public:
+ static void go (AST::Item *item)
+ {
+ ResolveItem resolver;
+ item->accept_vis (resolver);
+ };
+
+ ~ResolveItem () {}
+
+ void visit (AST::Function &function)
+ {
+ if (function.has_return_type ())
+ ResolveType::go (function.get_return_type ().get (),
+ function.get_node_id ());
+
+ for (auto &param : function.get_function_params ())
+ {
+ ResolveType::go (param.get_type ().get (), param.get_node_id ());
+ PatternDeclaration::go (param.get_pattern ().get (),
+ param.get_node_id ());
+ }
+
+ function.get_definition ()->iterate_stmts (
+ [&] (AST::Stmt *s) mutable -> bool {
+ // TODO
+ return true;
+ });
+ }
+
+private:
+ ResolveItem () : ResolverBase (UNKNOWN_NODEID) {}
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_AST_RESOLVE_ITEM_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.h b/gcc/rust/resolve/rust-ast-resolve-pattern.h
new file mode 100644
index 0000000..fc2da70
--- /dev/null
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.h
@@ -0,0 +1,97 @@
+// 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_AST_RESOLVE_PATTERN_H
+#define RUST_AST_RESOLVE_PATTERN_H
+
+#include "rust-ast-resolve-base.h"
+#include "rust-ast-full.h"
+
+namespace Rust {
+namespace Resolver {
+
+class ResolvePattern : public ResolverBase
+{
+public:
+ static void go (AST::Pattern *pattern, NodeId parent)
+ {
+ ResolvePattern resolver (parent);
+
+ pattern->accept_vis (resolver);
+ if (resolver.resolved_node == UNKNOWN_NODEID)
+ {
+ rust_error_at (resolver.locus, "failed to resolve pattern %s",
+ pattern->as_string ().c_str ());
+ }
+ };
+
+ ~ResolvePattern () {}
+
+ void visit (AST::IdentifierPattern &pattern)
+ {
+ if (resolver->get_name_scope ().lookup (pattern.get_ident (),
+ &resolved_node))
+ {
+ resolver->insert_resolved_name (pattern.get_node_id (), resolved_node);
+ resolver->insert_new_definition (pattern.get_node_id (),
+ Definition{pattern.get_node_id (),
+ parent});
+ }
+ }
+
+private:
+ ResolvePattern (NodeId parent) : ResolverBase (parent) {}
+};
+
+class PatternDeclaration : public ResolverBase
+{
+public:
+ static void go (AST::Pattern *pattern, NodeId parent)
+ {
+ PatternDeclaration resolver (parent);
+
+ pattern->accept_vis (resolver);
+ if (resolver.resolved_node != UNKNOWN_NODEID)
+ {
+ // print both locations?!
+ rust_error_at (resolver.locus, "duplicate pattern %s",
+ pattern->as_string ().c_str ());
+ }
+ };
+
+ ~PatternDeclaration () {}
+
+ void visit (AST::IdentifierPattern &pattern)
+ {
+ // if we have a duplicate id this then allows for shadowing correctly
+ // as new refs to this decl will match back here so it is ok to overwrite
+ resolver->get_name_scope ().insert (pattern.get_ident (),
+ pattern.get_node_id ());
+ resolver->insert_new_definition (pattern.get_node_id (),
+ Definition{pattern.get_node_id (),
+ parent});
+ }
+
+private:
+ PatternDeclaration (NodeId parent) : ResolverBase (parent) {}
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_AST_RESOLVE_PATTERN_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h
new file mode 100644
index 0000000..42fb097
--- /dev/null
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h
@@ -0,0 +1,59 @@
+// 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_AST_RESOLVE_STMT_H
+#define RUST_AST_RESOLVE_STMT_H
+
+#include "rust-ast-resolve-base.h"
+#include "rust-ast-full.h"
+#include "rust-ast-resolve-type.h"
+#include "rust-ast-resolve-pattern.h"
+#include "rust-ast-resolve-expr.h"
+
+namespace Rust {
+namespace Resolver {
+
+class ResolveStmt : public ResolverBase
+{
+public:
+ static void go (AST::Stmt *stmt, NodeId parent)
+ {
+ ResolveStmt resolver (parent);
+ stmt->accept_vis (resolver);
+ };
+
+ ~ResolveStmt () {}
+
+ void visit (AST::LetStmt &stmt)
+ {
+ PatternDeclaration::go (stmt.variables_pattern.get (), stmt.get_node_id ());
+ if (stmt.has_type ())
+ ResolveType::go (stmt.type.get (), stmt.get_node_id ());
+
+ if (stmt.has_init_expr ())
+ ResolveExpr::go (stmt.init_expr.get (), stmt.get_node_id ());
+ }
+
+private:
+ ResolveStmt () : ResolverBase (UNKNOWN_NODEID) {}
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_AST_RESOLVE_STMT_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
new file mode 100644
index 0000000..fcc9663
--- /dev/null
+++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
@@ -0,0 +1,54 @@
+// 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_AST_RESOLVE_TOPLEVEL_H
+#define RUST_AST_RESOLVE_TOPLEVEL_H
+
+#include "rust-ast-resolve-base.h"
+#include "rust-ast-full.h"
+
+namespace Rust {
+namespace Resolver {
+
+class ResolveTopLevel : public ResolverBase
+{
+public:
+ static void go (AST::Item *item)
+ {
+ ResolveTopLevel resolver;
+ item->accept_vis (resolver);
+ };
+
+ ~ResolveTopLevel () {}
+
+ void visit (AST::Function &function)
+ {
+ // function_names are simple std::String identifiers so this can be a
+ // NodeId mapping to the Function node
+ resolver->get_name_scope ().insert (function.get_function_name (),
+ function.get_node_id ());
+ }
+
+private:
+ ResolveTopLevel () : ResolverBase (UNKNOWN_NODEID) {}
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_AST_RESOLVE_TOPLEVEL_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
new file mode 100644
index 0000000..3cffa77
--- /dev/null
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -0,0 +1,66 @@
+// 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_AST_RESOLVE_TYPE_H
+#define RUST_AST_RESOLVE_TYPE_H
+
+#include "rust-ast-resolve-base.h"
+#include "rust-ast-full.h"
+
+namespace Rust {
+namespace Resolver {
+
+class ResolveType : public ResolverBase
+{
+public:
+ static void go (AST::Type *type, NodeId parent)
+ {
+ ResolveType resolver (parent);
+
+ type->accept_vis (resolver);
+ if (resolver.resolved_node == UNKNOWN_NODEID)
+ {
+ rust_error_at (resolver.locus, "failed to resolve type %s",
+ type->as_string ().c_str ());
+ }
+ };
+
+ ~ResolveType () {}
+
+ virtual void visit (AST::TypePath &path)
+ {
+ // this will need changed to handle mod/crate/use globs and look
+ // at the segments in granularity
+ locus = path.get_locus ();
+ if (resolver->get_type_scope ().lookup (path.as_string (), &resolved_node))
+ {
+ resolver->insert_resolved_type (path.get_node_id (), resolved_node);
+ resolver->insert_new_definition (path.get_node_id (),
+ Definition{path.get_node_id (),
+ parent});
+ }
+ }
+
+private:
+ ResolveType (NodeId parent) : ResolverBase (parent) {}
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_AST_RESOLVE_TYPE_H
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
new file mode 100644
index 0000000..664af12
--- /dev/null
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -0,0 +1,245 @@
+// 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-ast-resolve.h"
+#include "rust-ast-resolve-toplevel.h"
+#include "rust-ast-resolve-item.h"
+#include "rust-ast-full.h"
+
+#define MKBUILTIN_TYPE(_X, _R) \
+ do \
+ { \
+ AST::PathIdentSegment seg (_X); \
+ auto typePath = ::std::unique_ptr<AST::TypePathSegment> ( \
+ new AST::TypePathSegment (::std::move (seg), false, \
+ Linemap::predeclared_location ())); \
+ ::std::vector< ::std::unique_ptr<AST::TypePathSegment> > segs; \
+ segs.push_back (::std::move (typePath)); \
+ auto builtin_type \
+ = new AST::TypePath (::std::move (segs), \
+ Linemap::predeclared_location (), false); \
+ _R.push_back (builtin_type); \
+ } \
+ while (0)
+
+namespace Rust {
+namespace Resolver {
+
+// Resolver
+
+Resolver::Resolver ()
+ : mappings (Analysis::Mappings::get ()),
+ name_scope (Scope (mappings->get_current_crate ())),
+ type_scope (Scope (mappings->get_current_crate ()))
+{
+ generate_builtins ();
+}
+
+Resolver *
+Resolver::get ()
+{
+ static Resolver *instance;
+ if (instance == nullptr)
+ instance = new Resolver ();
+
+ return instance;
+}
+
+void
+Resolver::push_new_name_rib (Rib *r)
+{
+ rust_assert (name_ribs.find (r->get_node_id ()) == name_ribs.end ());
+ name_ribs[r->get_node_id ()] = r;
+}
+
+void
+Resolver::push_new_type_rib (Rib *r)
+{
+ if (type_ribs.size () == 0)
+ global_type_node_id = r->get_node_id ();
+
+ rust_assert (type_ribs.find (r->get_node_id ()) == type_ribs.end ());
+ type_ribs[r->get_node_id ()] = r;
+}
+
+bool
+Resolver::find_name_rib (NodeId id, Rib **rib)
+{
+ auto it = name_ribs.find (id);
+ if (it == name_ribs.end ())
+ return false;
+
+ *rib = it->second;
+ return true;
+}
+
+bool
+Resolver::find_type_rib (NodeId id, Rib **rib)
+{
+ auto it = type_ribs.find (id);
+ if (it == type_ribs.end ())
+ return false;
+
+ *rib = it->second;
+ return true;
+}
+
+void
+Resolver::insert_builtin_types (Rib *r)
+{
+ auto builtins = get_builtin_types ();
+ for (auto it = builtins.begin (); it != builtins.end (); it++)
+ r->insert_name ((*it)->as_string (), (*it)->get_node_id ());
+}
+
+std::vector<AST::TypePath *> &
+Resolver::get_builtin_types ()
+{
+ return builtins;
+}
+
+void
+Resolver::generate_builtins ()
+{
+ MKBUILTIN_TYPE ("u8", builtins);
+ MKBUILTIN_TYPE ("u16", builtins);
+ MKBUILTIN_TYPE ("u32", builtins);
+ MKBUILTIN_TYPE ("u64", builtins);
+
+ MKBUILTIN_TYPE ("i8", builtins);
+ MKBUILTIN_TYPE ("i16", builtins);
+ MKBUILTIN_TYPE ("i32", builtins);
+ MKBUILTIN_TYPE ("i64", builtins);
+
+ MKBUILTIN_TYPE ("f32", builtins);
+ MKBUILTIN_TYPE ("f64", builtins);
+
+ MKBUILTIN_TYPE ("char", builtins);
+ MKBUILTIN_TYPE ("str", builtins);
+ MKBUILTIN_TYPE ("bool", builtins);
+}
+
+void
+Resolver::insert_new_definition (NodeId id, Definition def)
+{
+ auto it = name_definitions.find (id);
+ rust_assert (it == name_definitions.end ());
+
+ name_definitions[id] = def;
+}
+
+bool
+Resolver::lookup_definition (NodeId id, Definition *def)
+{
+ auto it = name_definitions.find (id);
+ if (it == name_definitions.end ())
+ return false;
+
+ *def = it->second;
+ return true;
+}
+
+void
+Resolver::insert_resolved_name (NodeId refId, NodeId defId)
+{
+ auto it = resolved_names.find (refId);
+ rust_assert (it == resolved_names.end ());
+
+ resolved_names[refId] = defId;
+}
+
+bool
+Resolver::lookup_resolved_name (NodeId refId, NodeId *defId)
+{
+ auto it = resolved_names.find (refId);
+ if (it == resolved_names.end ())
+ return false;
+
+ *defId = it->second;
+ return true;
+}
+
+void
+Resolver::insert_resolved_type (NodeId refId, NodeId defId)
+{
+ auto it = resolved_types.find (refId);
+ rust_assert (it == resolved_types.end ());
+
+ resolved_types[refId] = defId;
+}
+
+bool
+Resolver::lookup_resolved_type (NodeId refId, NodeId *defId)
+{
+ auto it = resolved_types.find (refId);
+ if (it == resolved_types.end ())
+ return false;
+
+ *defId = it->second;
+ return true;
+}
+
+// NameResolution
+
+NameResolution *
+NameResolution::get ()
+{
+ static NameResolution *instance;
+ if (instance == nullptr)
+ instance = new NameResolution ();
+
+ return instance;
+}
+
+NameResolution::NameResolution ()
+ : resolver (Resolver::get ()), mappings (Analysis::Mappings::get ())
+{
+ // these are global
+ resolver->get_type_scope ().push (mappings->get_next_node_id ());
+ resolver->insert_builtin_types (resolver->get_type_scope ().peek ());
+ resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
+}
+
+void
+NameResolution::Resolve (AST::Crate &crate)
+{
+ auto resolver = get ();
+ resolver->go (crate);
+}
+
+void
+NameResolution::go (AST::Crate &crate)
+{
+ // setup parent scoping for names
+ resolver->get_name_scope ().push (crate.get_node_id ());
+ resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
+ // setup parent scoping for new types
+ resolver->get_type_scope ().push (mappings->get_next_node_id ());
+ resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
+
+ // first gather the top-level namespace names then we drill down
+ for (auto it = crate.items.begin (); it != crate.items.end (); it++)
+ ResolveTopLevel::go (it->get ());
+
+ // next we can drill down into the items and their scopes
+ for (auto it = crate.items.begin (); it != crate.items.end (); it++)
+ ResolveItem::go (it->get ());
+}
+
+} // namespace Resolver
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve.h b/gcc/rust/resolve/rust-ast-resolve.h
new file mode 100644
index 0000000..29ae0ab
--- /dev/null
+++ b/gcc/rust/resolve/rust-ast-resolve.h
@@ -0,0 +1,50 @@
+// 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_AST_RESOLVE_H
+#define RUST_AST_RESOLVE_H
+
+#include "rust-name-resolver.h"
+#include "rust-ast-full.h"
+#include "rust-hir-map.h"
+
+namespace Rust {
+namespace Resolver {
+
+class NameResolution
+{
+public:
+ static void Resolve (AST::Crate &crate);
+
+ static NameResolution *get ();
+
+ ~NameResolution () {}
+
+private:
+ void go (AST::Crate &crate);
+
+ NameResolution ();
+
+ Resolver *resolver;
+ Analysis::Mappings *mappings;
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_AST_RESOLVE_H
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
new file mode 100644
index 0000000..4aac7d5
--- /dev/null
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -0,0 +1,211 @@
+// 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_NAME_RESOLVER_H
+#define RUST_NAME_RESOLVER_H
+
+#include "rust-system.h"
+#include "rust-hir-map.h"
+
+namespace Rust {
+namespace Resolver {
+
+class Rib
+{
+public:
+ // Rusts uses local_def_ids assigned by def_collector on the AST
+ // lets use NodeId instead
+ Rib (CrateNum crateNum, NodeId node_id)
+ : crate_num (crateNum), node_id (node_id)
+ {}
+
+ ~Rib () {}
+
+ void insert_name (std::string ident, NodeId id)
+ {
+ mappings[ident] = id;
+ decls_within_rib.insert (id);
+ }
+
+ bool lookup_name (std::string ident, NodeId *id)
+ {
+ auto it = mappings.find (ident);
+ if (it == mappings.end ())
+ return false;
+
+ *id = it->second;
+ return true;
+ }
+
+ CrateNum get_crate_num () const { return crate_num; }
+ NodeId get_node_id () const { return node_id; }
+
+private:
+ CrateNum crate_num;
+ NodeId node_id;
+ std::map<std::string, NodeId> mappings;
+ std::set<NodeId> decls_within_rib;
+};
+
+class Scope
+{
+public:
+ Scope (CrateNum crate_num) : crate_num (crate_num) {}
+ ~Scope () {}
+
+ void insert (std::string ident, NodeId id)
+ {
+ peek ()->insert_name (ident, id);
+ }
+
+ bool lookup (std::string ident, NodeId *id)
+ {
+ NodeId lookup = UNKNOWN_NODEID;
+ iterate ([&] (Rib *r) mutable -> bool {
+ if (r->lookup_name (ident, &lookup))
+ return false;
+ return true;
+ });
+
+ *id = lookup;
+ return lookup != UNKNOWN_NODEID;
+ }
+
+ void iterate (std::function<bool (Rib *)> cb)
+ {
+ for (auto it = stack.rbegin (); it != stack.rend (); ++it)
+ {
+ if (!cb (*it))
+ return;
+ }
+ }
+
+ Rib *peek () { return stack.back (); }
+
+ void push (NodeId id) { stack.push_back (new Rib (get_crate_num (), id)); }
+
+ Rib *pop ()
+ {
+ Rib *r = peek ();
+ stack.pop_back ();
+ return r;
+ }
+
+ CrateNum get_crate_num () const { return crate_num; }
+
+private:
+ CrateNum crate_num;
+ std::vector<Rib *> stack;
+};
+
+// This can map simple NodeIds for names to their parent node
+// for example:
+//
+// var x = y + 1;
+//
+// say y has node id=1 and the plus_expression has id=2
+// then the Definition will have
+// Definition { node=1, parent=2 }
+// this will be used later to gather the ribs for the type inferences context
+//
+// if parent is UNKNOWN_NODEID then this is a root declaration
+// say the var_decl hasa node_id=4;
+// the parent could be a BLOCK_Expr node_id but lets make it UNKNOWN_NODE_ID so
+// we know when it terminates
+struct Definition
+{
+ NodeId node;
+ NodeId parent;
+ // add kind ?
+};
+
+class Resolver
+{
+public:
+ static Resolver *get ();
+ ~Resolver () {}
+
+ // these builtin types
+ void insert_builtin_types (Rib *r);
+
+ // these will be required for type resolution passes to
+ // map back to tyty nodes
+ std::vector<AST::TypePath *> &get_builtin_types ();
+
+ void push_new_name_rib (Rib *r);
+ void push_new_type_rib (Rib *r);
+
+ bool find_name_rib (NodeId id, Rib **rib);
+ bool find_type_rib (NodeId id, Rib **rib);
+
+ void insert_new_definition (NodeId id, Definition def);
+ bool lookup_definition (NodeId id, Definition *def);
+
+ void insert_resolved_name (NodeId refId, NodeId defId);
+ bool lookup_resolved_name (NodeId refId, NodeId *defId);
+
+ void insert_resolved_type (NodeId refId, NodeId defId);
+ bool lookup_resolved_type (NodeId refId, NodeId *defId);
+
+ // proxy for scoping
+ Scope &get_name_scope () { return name_scope; }
+ Scope &get_type_scope () { return type_scope; }
+
+ NodeId get_global_type_node_id () { return global_type_node_id; }
+
+private:
+ Resolver ();
+
+ void generate_builtins ();
+
+ Analysis::Mappings *mappings;
+
+ std::vector<AST::TypePath *> builtins;
+
+ Scope name_scope;
+ Scope type_scope;
+
+ NodeId global_type_node_id;
+
+ // map a AST Node to a Rib
+ std::map<NodeId, Rib *> name_ribs;
+ std::map<NodeId, Rib *> type_ribs;
+
+ // map any Node to its Definition
+ // ie any name or type usage
+ std::map<NodeId, Definition> name_definitions;
+
+ // Rust uses DefIds to namespace these under a crate_num
+ // but then it uses the def_collector to assign local_defids
+ // to each ast node as well. not sure if this is going to fit
+ // with gcc very well to compile a full crate in one go but we will
+ // see.
+
+ // these are of the form ref->Def-NodeId
+ // we need two namespaces one for names and ones for types
+ std::map<NodeId, NodeId> resolved_names;
+ std::map<NodeId, NodeId> resolved_types;
+
+ std::map<NodeId, std::set<NodeId> > nameDefNodeIdToRibs;
+ std::map<NodeId, std::set<NodeId> > typeDefNodeIdToRibs;
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_NAME_RESOLVER_H
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index f526da1..3131af0 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -29,14 +29,13 @@
#include "rust-lex.h"
#include "rust-parse.h"
#include "rust-scan.h"
-#include "rust-name-resolution.h"
-#include "rust-type-resolution.h"
#include "rust-macro-expand.h"
#include "rust-compile.h"
+#include "rust-target.h"
// hir passes wip
+#include "rust-ast-resolve.h"
#include "rust-ast-lower.h"
-#include "rust-target.h"
extern Linemap *
rust_get_linemap ();
@@ -399,6 +398,10 @@ Session::enable_dump (std::string arg)
// return false;
options.dump_option = CompileOptions::TARGET_OPTION_DUMP;
}
+ else if (arg == "hir")
+ {
+ options.dump_option = CompileOptions::HIR_DUMP;
+ }
else if (arg == "")
{
rust_error_at (Location (), "dump option was not given a name. choose "
@@ -527,6 +530,17 @@ Session::parse_file (const char *filename)
// TODO: what do I dump here? resolved names? AST with resolved names?
}
+ // lower AST to HIR
+ HIR::Crate hir = HIR::ASTLowering::Resolve (parsed_crate);
+ if (options.dump_option == CompileOptions::HIR_DUMP)
+ {
+ fprintf (stderr, "%s", hir.as_string ().c_str ());
+ return;
+ }
+
+ // type resolve
+ // TODO
+
if (saw_errors ())
return;
@@ -759,16 +773,7 @@ void
Session::resolution (AST::Crate &crate)
{
fprintf (stderr, "started name resolution\n");
- Analysis::TopLevelScan toplevel (crate);
- // Name resolution must be in front of type resolution
- Analysis::NameResolution::Resolve (crate, toplevel);
- Analysis::TypeResolution::Resolve (crate, toplevel);
-
- // inject hir passes
- HIR::Crate hir = HIR::ASTLowering::Resolve (crate);
- fprintf (stderr, "HIR PASSES:\n");
- fprintf (stderr, "%s", hir.as_string ().c_str ());
- fprintf (stderr, "HIR PASSES - DONE:\n");
+ Resolver::NameResolution::Resolve (crate);
fprintf (stderr, "finished name resolution\n");
}
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index bdeeeec..2bb1dfb 100644
--- a/gcc/rust/rust-session-manager.h
+++ b/gcc/rust/rust-session-manager.h
@@ -1,6 +1,24 @@
+// 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-session-manager.h"
+
#ifndef RUST_SESSION_MANAGER_H
#define RUST_SESSION_MANAGER_H
-// Session manager - controls compiler session.
#include "config.h"
#include "system.h"
@@ -11,12 +29,6 @@
#include "rust-linemap.h"
#include "rust-backend.h"
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-#include <utility>
-
namespace Rust {
// parser forward decl
template <typename ManagedTokenSource> class Parser;
@@ -32,7 +44,7 @@ struct TargetOptions
{
/* TODO: maybe make private and access through helpers to allow changes to
* impl */
- std::unordered_map<std::string, std::unordered_set<std::string>> features;
+ std::unordered_map<std::string, std::unordered_set<std::string> > features;
public:
// Returns whether a key is defined in the feature set.
@@ -160,6 +172,7 @@ struct CompileOptions
EXPANSION_DUMP,
RESOLUTION_DUMP,
TARGET_OPTION_DUMP,
+ HIR_DUMP,
// TODO: add more?
} dump_option;
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index ff3e548..094d0e3 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -64,10 +64,16 @@ NodeMapping::get_local_defid () const
DefId
NodeMapping::get_defid () const
{
+ return get_defid (get_crate_num (), get_local_defid ());
+}
+
+DefId
+NodeMapping::get_defid (CrateNum crate_num, LocalDefId local_defid)
+{
DefId val = 0;
- val |= get_crate_num ();
+ val |= crate_num;
val = val << sizeof (uint32_t);
- val |= get_local_defid ();
+ val |= local_defid;
return val;
}
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index cbe22a5..8929ca4 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -63,6 +63,8 @@ public:
LocalDefId get_local_defid () const;
DefId get_defid () const;
+ static DefId get_defid (CrateNum crate_num, LocalDefId local_defid);
+
std::string as_string () const;
private:
@@ -126,6 +128,9 @@ private:
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;
+
+ // reverse mappings
+ std::map<CrateNum, std::map<NodeId, HirId> > nodeIdToHirMappings;
};
} // namespace Analysis