diff options
author | Kushal Pal <kushalpal109@gmail.com> | 2024-01-26 11:35:24 +0530 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2024-02-07 12:40:24 +0100 |
commit | 41cbf917de55341069efa389ec21f90a1197da53 (patch) | |
tree | 39ccdca02bb21e0d009b88bc5ea9fa1925e01c26 /gcc | |
parent | 4be51abd5e829b2b9e8f4b7bc48212c17cf4c3f9 (diff) | |
download | gcc-41cbf917de55341069efa389ec21f90a1197da53.zip gcc-41cbf917de55341069efa389ec21f90a1197da53.tar.gz gcc-41cbf917de55341069efa389ec21f90a1197da53.tar.bz2 |
gccrs: Add missing visitors for AST::Function.
To use AST::Function instead of AST::TraitItemFunc and
AST::TraitItemMethod, we need to provide similar visitors during
lowering and resolving phase.
gcc/rust/ChangeLog:
* hir/rust-ast-lower-implitem.cc (ASTLowerTraitItem::visit):
Provide visitor for AST::Function.
* hir/rust-ast-lower-implitem.h:
Likewise.
* resolve/rust-ast-resolve-implitem.h:
Likewise.
* resolve/rust-ast-resolve-item.cc (ResolveTraitItems::visit):
Likewise.
* resolve/rust-ast-resolve-item.h:
Likewise.
Signed-off-by: Kushal Pal <kushalpal109@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-implitem.cc | 86 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-implitem.h | 1 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-implitem.h | 20 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-item.cc | 88 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-item.h | 1 |
5 files changed, 196 insertions, 0 deletions
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc index 98db1dc..77230e7 100644 --- a/gcc/rust/hir/rust-ast-lower-implitem.cc +++ b/gcc/rust/hir/rust-ast-lower-implitem.cc @@ -228,6 +228,92 @@ ASTLowerTraitItem::translate (AST::AssociatedItem *item) } void +ASTLowerTraitItem::visit (AST::Function &func) +{ + std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + HIR::WhereClause where_clause (std::move (where_clause_items)); + HIR::FunctionQualifiers qualifiers + = lower_qualifiers (func.get_qualifiers ()); + + std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + if (func.has_generics ()) + generic_params = lower_generic_params (func.get_generic_params ()); + + std::unique_ptr<HIR::Type> return_type + = func.has_return_type () ? std::unique_ptr<HIR::Type> ( + ASTLoweringType::translate (func.get_return_type ().get ())) + : nullptr; + + // set self parameter to error if this is a method + // else lower to hir + HIR::SelfParam self_param = func.has_self_param () + ? lower_self (func.get_self_param ()) + : HIR::SelfParam::error (); + + std::vector<HIR::FunctionParam> function_params; + for (auto &p : func.get_function_params ()) + { + if (p->is_variadic () || p->is_self ()) + continue; + + auto param = static_cast<AST::FunctionParam *> (p.get ()); + + auto translated_pattern = std::unique_ptr<HIR::Pattern> ( + ASTLoweringPattern::translate (param->get_pattern ().get ())); + auto translated_type = std::unique_ptr<HIR::Type> ( + ASTLoweringType::translate (param->get_type ().get ())); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, param->get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + auto hir_param + = HIR::FunctionParam (mapping, std::move (translated_pattern), + std::move (translated_type), param->get_locus ()); + function_params.push_back (hir_param); + } + + HIR::TraitFunctionDecl decl (func.get_function_name (), + std::move (qualifiers), + std::move (generic_params), + std::move (self_param), + std::move (function_params), + std::move (return_type), + std::move (where_clause)); + bool terminated = false; + std::unique_ptr<HIR::BlockExpr> block_expr + = func.has_body () ? std::unique_ptr<HIR::BlockExpr> ( + ASTLoweringBlock::translate (func.get_definition ()->get (), + &terminated)) + : nullptr; + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, func.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + auto *trait_item + = new HIR::TraitItemFunc (mapping, std::move (decl), std::move (block_expr), + func.get_outer_attrs (), func.get_locus ()); + translated = trait_item; + if (func.has_self_param ()) + { + // insert mappings for self + mappings->insert_hir_self_param (&self_param); + mappings->insert_location (self_param.get_mappings ().get_hirid (), + self_param.get_locus ()); + } + + // add the mappings for the function params at the end + for (auto ¶m : trait_item->get_decl ().get_function_params ()) + { + mappings->insert_hir_param (¶m); + mappings->insert_location (mapping.get_hirid (), param.get_locus ()); + } +} + +void ASTLowerTraitItem::visit (AST::TraitItemFunc &func) { AST::TraitFunctionDecl &ref = func.get_trait_function_decl (); diff --git a/gcc/rust/hir/rust-ast-lower-implitem.h b/gcc/rust/hir/rust-ast-lower-implitem.h index 3a266b4..b9d12cc 100644 --- a/gcc/rust/hir/rust-ast-lower-implitem.h +++ b/gcc/rust/hir/rust-ast-lower-implitem.h @@ -48,6 +48,7 @@ class ASTLowerTraitItem : public ASTLoweringBase public: static HIR::TraitItem *translate (AST::AssociatedItem *item); + void visit (AST::Function &func) override; void visit (AST::TraitItemFunc &func) override; void visit (AST::TraitItemMethod &method) override; void visit (AST::TraitItemConst &constant) override; diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h index 365bdd61..d9c9bcb 100644 --- a/gcc/rust/resolve/rust-ast-resolve-implitem.h +++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h @@ -110,6 +110,26 @@ public: item->accept_vis (resolver); }; + void visit (AST::Function &function) override + { + auto decl + = CanonicalPath::new_seg (function.get_node_id (), + function.get_function_name ().as_string ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + + resolver->get_name_scope ().insert ( + path, function.get_node_id (), function.get_locus (), false, + Rib::ItemType::Function, + [&] (const CanonicalPath &, NodeId, location_t locus) -> void { + rich_location r (line_table, function.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + + mappings->insert_canonical_path (function.get_node_id (), cpath); + } + void visit (AST::TraitItemFunc &function) override { auto decl = CanonicalPath::new_seg ( diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc index 60eca5b..6037fe5 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.cc +++ b/gcc/rust/resolve/rust-ast-resolve-item.cc @@ -46,6 +46,94 @@ ResolveTraitItems::go (AST::AssociatedItem *item, const CanonicalPath &prefix, } void +ResolveTraitItems::visit (AST::Function &function) +{ + auto decl + = CanonicalPath::new_seg (function.get_node_id (), + function.get_function_name ().as_string ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (function.get_node_id (), cpath); + + NodeId scope_node_id = function.get_node_id (); + resolver->get_name_scope ().push (scope_node_id); + resolver->get_type_scope ().push (scope_node_id); + resolver->get_label_scope ().push (scope_node_id); + resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); + resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); + resolver->push_new_label_rib (resolver->get_type_scope ().peek ()); + + if (function.has_generics ()) + for (auto &generic : function.get_generic_params ()) + ResolveGenericParam::go (generic.get (), prefix, canonical_prefix); + + if (function.has_return_type ()) + ResolveType::go (function.get_return_type ().get ()); + + // self turns into (self: Self) as a function param + std::vector<PatternBinding> bindings + = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())}; + + // we make a new scope so the names of parameters are resolved and shadowed + // correctly + for (auto &p : function.get_function_params ()) + { + if (p->is_variadic ()) + { + auto param = static_cast<AST::VariadicParam *> (p.get ()); + PatternDeclaration::go (param->get_pattern ().get (), + Rib::ItemType::Param, bindings); + } + else if (p->is_self ()) + { + auto param = static_cast<AST::SelfParam *> (p.get ()); + // FIXME: which location should be used for Rust::Identifier `self`? + AST::IdentifierPattern self_pattern ( + param->get_node_id (), {"self"}, param->get_locus (), + param->get_has_ref (), param->get_is_mut (), + std::unique_ptr<AST::Pattern> (nullptr)); + + PatternDeclaration::go (&self_pattern, Rib::ItemType::Param); + + if (param->has_type ()) + { + // This shouldn't happen the parser should already error for this + rust_assert (!param->get_has_ref ()); + ResolveType::go (param->get_type ().get ()); + } + else + { + // here we implicitly make self have a type path of Self + std::vector<std::unique_ptr<AST::TypePathSegment>> segments; + segments.push_back (std::unique_ptr<AST::TypePathSegment> ( + new AST::TypePathSegment ("Self", false, param->get_locus ()))); + + AST::TypePath self_type_path (std::move (segments), + param->get_locus ()); + ResolveType::go (&self_type_path); + } + } + else + { + auto param = static_cast<AST::FunctionParam *> (p.get ()); + ResolveType::go (param->get_type ().get ()); + PatternDeclaration::go (param->get_pattern ().get (), + Rib::ItemType::Param, bindings); + } + } + + if (function.has_where_clause ()) + ResolveWhereClause::Resolve (function.get_where_clause ()); + + // trait items have an optional body + if (function.has_body ()) + ResolveExpr::go (function.get_definition ()->get (), path, cpath); + + resolver->get_name_scope ().pop (); + resolver->get_type_scope ().pop (); + resolver->get_label_scope ().pop (); +} +void ResolveTraitItems::visit (AST::TraitItemType &type) { auto decl = CanonicalPath::new_seg (type.get_node_id (), diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h index 712fe62..33a78e2 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.h +++ b/gcc/rust/resolve/rust-ast-resolve-item.h @@ -35,6 +35,7 @@ public: static void go (AST::AssociatedItem *item, const CanonicalPath &prefix, const CanonicalPath &canonical_prefix); + void visit (AST::Function &type) override; void visit (AST::TraitItemType &type) override; void visit (AST::TraitItemFunc &func) override; void visit (AST::TraitItemMethod &func) override; |