aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-09-27 14:06:08 +0000
committerGitHub <noreply@github.com>2022-09-27 14:06:08 +0000
commitb71e3dc02a8fd3141080419b7fb1a24d2c4133d0 (patch)
tree44b3a95ad14a292d10c025127cdf235480154194 /gcc/rust/backend
parentcecd314884a285957a110560bbd141a5f39ad7d3 (diff)
parentb17e69852ea999547305b19e9c8da385f6c31e1e (diff)
downloadgcc-b71e3dc02a8fd3141080419b7fb1a24d2c4133d0.zip
gcc-b71e3dc02a8fd3141080419b7fb1a24d2c4133d0.tar.gz
gcc-b71e3dc02a8fd3141080419b7fb1a24d2c4133d0.tar.bz2
Merge #1545
1545: Refactor TypeResolution to be a simple query based system r=philberty a=philberty This patch refactors the type resolution system to introduce a new interface bool query_type (HirId, TyTy::BaseType** result) This is needed in order to properly support forward declared items. Our name resolution system has two parts: 1. Toplevel scan 2. Item resolution The toplevel scan gathers all the nesseacry 'names' into their respective namespace by doing a full toplevel scan and generate canonical paths for each item. The second pass is responsible for drilling down into each structure or function to resolve each field or variable etc. This means our name resolution system supports forward decalred items but our type resolution system did not. This patch removes the toplevel scan from our type resolution pass which is not able to handle all cases such as a function with return type and the type is decalred after the fact or a type alias to a type declared after the fact. The name resolution mappings are resolved so when errors occured here we got errors such as unable to lookup HirId 1234, which meant yes we have 'resolved' this reference to this HirId but we are unable to find any type information for it. This means we needed a new way to figure out the type in a query based way. This is where the new query_type inferface comes in so when we have an HirId we want to resolve the mappings class allows us to figure out what item this is such as: 1. HIR::Item (normal HIR::Function, Struct, TypeAlias, ...) 2. HIR::ImplItem (function, constant, ... within an impl-block) 3. HIR::ImplBlock (Self type on an impl-block) 4. HIR::ExternalItem (extern-block item) The mappings class allows us to simply lookup these HIR nodes and then call the relevant resolver class to compute the type. This patch does not add support for self-referencial types but is the starting point to be able to support such types. Fixes #1455 Fixes #1006 Fixes #1073 Fixes #1272 Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r--gcc/rust/backend/rust-compile-context.h21
-rw-r--r--gcc/rust/backend/rust-compile-expr.h17
-rw-r--r--gcc/rust/backend/rust-compile-item.cc14
-rw-r--r--gcc/rust/backend/rust-constexpr.cc16
4 files changed, 48 insertions, 20 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index 096b65f..415b13e 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -148,7 +148,8 @@ public:
}
bool lookup_function_decl (HirId id, tree *fn, DefId dId = UNKNOWN_DEFID,
- const TyTy::BaseType *ref = nullptr)
+ const TyTy::BaseType *ref = nullptr,
+ const std::string &asm_name = std::string ())
{
// for for any monomorphized fns
if (ref != nullptr)
@@ -163,11 +164,29 @@ public:
{
const TyTy::BaseType *r = e.first;
tree f = e.second;
+
if (ref->is_equal (*r))
{
*fn = f;
return true;
}
+
+ if (DECL_ASSEMBLER_NAME_SET_P (f) && !asm_name.empty ())
+ {
+ tree raw = DECL_ASSEMBLER_NAME_RAW (f);
+ const char *rptr = IDENTIFIER_POINTER (raw);
+
+ bool lengths_match_p
+ = IDENTIFIER_LENGTH (raw) == asm_name.size ();
+ if (lengths_match_p
+ && strncmp (rptr, asm_name.c_str (),
+ IDENTIFIER_LENGTH (raw))
+ == 0)
+ {
+ *fn = f;
+ return true;
+ }
+ }
}
return false;
}
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 4c1f95a..f5cb06d 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -68,24 +68,31 @@ public:
void visit (HIR::RangeFullExpr &expr) override;
void visit (HIR::RangeFromToInclExpr &expr) override;
- // Empty visit for unused Expression HIR nodes.
+ // TODO
void visit (HIR::ClosureExprInner &) override {}
void visit (HIR::ClosureExprInnerTyped &) override {}
- void visit (HIR::StructExprFieldIdentifier &) override {}
- void visit (HIR::StructExprFieldIdentifierValue &) override {}
- void visit (HIR::StructExprFieldIndexValue &) override {}
void visit (HIR::ErrorPropagationExpr &) override {}
void visit (HIR::RangeToInclExpr &) override {}
- void visit (HIR::WhileLetLoopExpr &) override {}
void visit (HIR::ForLoopExpr &) override {}
+
+ // TODO
+ // these need to be sugared in the HIR to if statements and a match
+ void visit (HIR::WhileLetLoopExpr &) override {}
void visit (HIR::IfExprConseqIfLet &) override {}
void visit (HIR::IfLetExpr &) override {}
void visit (HIR::IfLetExprConseqElse &) override {}
void visit (HIR::IfLetExprConseqIf &) override {}
void visit (HIR::IfLetExprConseqIfLet &) override {}
+
+ // lets not worry about async yet....
void visit (HIR::AwaitExpr &) override {}
void visit (HIR::AsyncBlockExpr &) override {}
+ // nothing to do for these
+ void visit (HIR::StructExprFieldIdentifier &) override {}
+ void visit (HIR::StructExprFieldIdentifierValue &) override {}
+ void visit (HIR::StructExprFieldIndexValue &) override {}
+
protected:
tree get_fn_addr_from_dyn (const TyTy::DynamicObjectType *dyn,
TyTy::BaseType *receiver, TyTy::FnType *fntype,
diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc
index 8ba17c9..27f3e64 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -134,11 +134,18 @@ CompileItem::visit (HIR::Function &function)
}
}
+ const Resolver::CanonicalPath *canonical_path = nullptr;
+ bool ok = ctx->get_mappings ()->lookup_canonical_path (
+ function.get_mappings ().get_nodeid (), &canonical_path);
+ rust_assert (ok);
+
+ const std::string asm_name = ctx->mangle_item (fntype, *canonical_path);
+
// items can be forward compiled which means we may not need to invoke this
// code. We might also have already compiled this generic function as well.
tree lookup = NULL_TREE;
if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
- fntype->get_id (), fntype))
+ fntype->get_id (), fntype, asm_name))
{
// has this been added to the list then it must be finished
if (ctx->function_completed (lookup))
@@ -160,11 +167,6 @@ CompileItem::visit (HIR::Function &function)
fntype->override_context ();
}
- const Resolver::CanonicalPath *canonical_path = nullptr;
- bool ok = ctx->get_mappings ()->lookup_canonical_path (
- function.get_mappings ().get_nodeid (), &canonical_path);
- rust_assert (ok);
-
if (function.get_qualifiers ().is_const ())
ctx->push_const_context ();
diff --git a/gcc/rust/backend/rust-constexpr.cc b/gcc/rust/backend/rust-constexpr.cc
index 203449b..790a8e9 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -2953,14 +2953,14 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, bool lval,
TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
CONSTRUCTOR_NO_CLEARING (*valp) = CONSTRUCTOR_NO_CLEARING (init);
}
- else if (TREE_CODE (init) == CONSTRUCTOR
- && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init),
- type))
- {
- /* See above on initialization of empty bases. */
- gcc_assert (is_empty_class (TREE_TYPE (init)) && !lval);
- return init;
- }
+ // else if (TREE_CODE (init) == CONSTRUCTOR
+ // && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init),
+ // type))
+ // {
+ // /* See above on initialization of empty bases. */
+ // // gcc_assert (is_empty_class (TREE_TYPE (init)) && !lval);
+ // return init;
+ // }
else
*valp = init;