diff options
author | Philip Herron <philip.herron@embecosm.com> | 2022-05-16 17:09:45 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2022-05-17 11:18:31 +0100 |
commit | 4a4206c017654af7a3468690e4e21fdaf86bcb5c (patch) | |
tree | 4ddbcbcb3a61bc12b5025c9bf1ea8316cdb5b083 /gcc | |
parent | e4213b9568ae8cb8a4e31326e0e78c79db0a99cc (diff) | |
download | gcc-4a4206c017654af7a3468690e4e21fdaf86bcb5c.zip gcc-4a4206c017654af7a3468690e4e21fdaf86bcb5c.tar.gz gcc-4a4206c017654af7a3468690e4e21fdaf86bcb5c.tar.bz2 |
Support extern-blocks defined within blocks
This adds support for declaring extern blocks within blocks. So this adds
the missing name resolution visitor for the statement context. Then we
extract out a common extern block hir lowering function for both contexts.
The type resolution step needs to be updated to be like the code-generation
step so that we can solve these paths in a query rather than a top down
approach but this is a known issue.
The final step was to support query based compilation to extern functions.
Fixes #976
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/Make-lang.in | 1 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-base.cc | 8 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-extern.h | 27 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 16 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-base.cc | 68 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-base.h | 2 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-item.cc | 41 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-stmt.h | 5 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-stmt.cc | 38 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-stmt.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-stmt.h | 9 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check.cc | 7 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/issue-976.rs | 14 |
13 files changed, 172 insertions, 66 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index 738cfdf..2d701ea 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -94,6 +94,7 @@ GRS_OBJS = \ rust/rust-ast-resolve-expr.o \ rust/rust-ast-resolve-type.o \ rust/rust-ast-resolve-path.o \ + rust/rust-ast-resolve-stmt.o \ rust/rust-hir-type-check.o \ rust/rust-privacy-check.o \ rust/rust-privacy-ctx.o \ diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc index 6773ac6..7b0a375 100644 --- a/gcc/rust/backend/rust-compile-base.cc +++ b/gcc/rust/backend/rust-compile-base.cc @@ -343,8 +343,12 @@ HIRCompileBase::compile_locals_for_block (Context *ctx, Resolver::Rib &rib, rust_assert (ok); HIR::Stmt *decl = nullptr; - ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl); - rust_assert (ok); + if (!ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl)) + { + // might be an extern block see fix for + // https://github.com/Rust-GCC/gccrs/issues/976 + continue; + } // if its a function we extract this out side of this fn context // and it is not a local to this function diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h index 1987805..c24437d 100644 --- a/gcc/rust/backend/rust-compile-extern.h +++ b/gcc/rust/backend/rust-compile-extern.h @@ -29,11 +29,19 @@ class CompileExternItem : public HIRCompileBase, public HIR::HIRExternalItemVisitor { public: - static void compile (HIR::ExternalItem *item, Context *ctx, - TyTy::BaseType *concrete = nullptr) + static tree compile (HIR::ExternalItem *item, Context *ctx, + TyTy::BaseType *concrete = nullptr, + bool is_query_mode = false, + Location ref_locus = Location ()) { - CompileExternItem compiler (ctx, concrete); + CompileExternItem compiler (ctx, concrete, ref_locus); item->accept_vis (compiler); + + if (is_query_mode && compiler.reference == error_mark_node) + rust_internal_error_at (ref_locus, "failed to compile extern item: %s", + item->as_string ().c_str ()); + + return compiler.reference; } void visit (HIR::ExternalStaticItem &item) override @@ -58,6 +66,8 @@ public: item.get_locus ()); ctx->insert_var_decl (item.get_mappings ().get_hirid (), static_global); ctx->push_var (static_global); + + reference = ctx->get_backend ()->var_expression (static_global, ref_locus); } void visit (HIR::ExternalFunctionItem &function) override @@ -129,14 +139,21 @@ public: setup_abi_options (fndecl, fntype->get_abi ()); ctx->insert_function_decl (fntype, fndecl); + + reference + = address_expression (fndecl, build_pointer_type (TREE_TYPE (fndecl)), + ref_locus); } private: - CompileExternItem (Context *ctx, TyTy::BaseType *concrete) - : HIRCompileBase (ctx), concrete (concrete) + CompileExternItem (Context *ctx, TyTy::BaseType *concrete, Location ref_locus) + : HIRCompileBase (ctx), concrete (concrete), reference (error_mark_node), + ref_locus (ref_locus) {} TyTy::BaseType *concrete; + tree reference; + Location ref_locus; }; } // namespace Compile diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index bd44bf4..ca96a27 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -23,8 +23,7 @@ #include "rust-compile-expr.h" #include "rust-hir-trait-resolve.h" #include "rust-hir-path-probe.h" - -#include "print-tree.h" +#include "rust-compile-extern.h" namespace Rust { namespace Compile { @@ -172,7 +171,11 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, { HIR::Item *resolved_item = ctx->get_mappings ()->lookup_hir_item (mappings.get_crate_num (), ref); + HIR::ExternalItem *resolved_extern_item + = ctx->get_mappings ()->lookup_hir_extern_item (mappings.get_crate_num (), + ref); bool is_hir_item = resolved_item != nullptr; + bool is_hir_extern_item = resolved_extern_item != nullptr; if (is_hir_item) { if (!lookup->has_subsititions_defined ()) @@ -182,6 +185,15 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, return CompileItem::compile (resolved_item, ctx, lookup, true, expr_locus); } + else if (is_hir_extern_item) + { + if (!lookup->has_subsititions_defined ()) + return CompileExternItem::compile (resolved_extern_item, ctx, nullptr, + true, expr_locus); + else + return CompileExternItem::compile (resolved_extern_item, ctx, lookup, + true, expr_locus); + } else { HirId parent_impl_id = UNKNOWN_HIRID; diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc index 7afe75c..a482132 100644 --- a/gcc/rust/hir/rust-ast-lower-base.cc +++ b/gcc/rust/hir/rust-ast-lower-base.cc @@ -19,6 +19,7 @@ #include "rust-ast-lower-base.h" #include "rust-ast-lower-type.h" #include "rust-ast-lower-pattern.h" +#include "rust-ast-lower-extern.h" namespace Rust { namespace HIR { @@ -545,11 +546,11 @@ ASTLoweringBase::lower_loop_label (AST::LoopLabel &loop_label) return HIR::LoopLabel (mapping, std::move (life), loop_label.get_locus ()); } -std::vector<std::unique_ptr<HIR::GenericParam> > +std::vector<std::unique_ptr<HIR::GenericParam>> ASTLoweringBase::lower_generic_params ( - std::vector<std::unique_ptr<AST::GenericParam> > ¶ms) + std::vector<std::unique_ptr<AST::GenericParam>> ¶ms) { - std::vector<std::unique_ptr<HIR::GenericParam> > lowered; + std::vector<std::unique_ptr<HIR::GenericParam>> lowered; for (auto &ast_param : params) { auto hir_param = ASTLowerGenericParam::translate (ast_param.get ()); @@ -601,7 +602,7 @@ ASTLoweringBase::lower_generic_args (AST::GenericArgs &args) lifetime_args.push_back (std::move (l)); } - std::vector<std::unique_ptr<HIR::Type> > type_args; + std::vector<std::unique_ptr<HIR::Type>> type_args; for (auto &type : args.get_type_args ()) { HIR::Type *t = ASTLoweringType::translate (type.get ()); @@ -653,7 +654,7 @@ ASTLowerTypePath::visit (AST::TypePathSegmentGeneric &segment) lifetime_args.push_back (std::move (l)); } - std::vector<std::unique_ptr<HIR::Type> > type_args; + std::vector<std::unique_ptr<HIR::Type>> type_args; for (auto &type : segment.get_generic_args ().get_type_args ()) { HIR::Type *t = ASTLoweringType::translate (type.get ()); @@ -700,7 +701,7 @@ ASTLowerQualifiedPathInType::visit (AST::QualifiedPathInType &path) } std::unique_ptr<HIR::TypePathSegment> associated_segment (translated_segment); - std::vector<std::unique_ptr<HIR::TypePathSegment> > translated_segments; + std::vector<std::unique_ptr<HIR::TypePathSegment>> translated_segments; for (auto &seg : path.get_segments ()) { translated_segment = nullptr; @@ -728,7 +729,7 @@ ASTLowerQualifiedPathInType::visit (AST::QualifiedPathInType &path) void ASTLoweringType::visit (AST::TraitObjectTypeOneBound &type) { - std::vector<std::unique_ptr<HIR::TypeParamBound> > bounds; + std::vector<std::unique_ptr<HIR::TypeParamBound>> bounds; HIR::TypeParamBound *translated_bound = ASTLoweringTypeBounds::translate (&type.get_trait_bound ()); bounds.push_back (std::unique_ptr<HIR::TypeParamBound> (translated_bound)); @@ -748,7 +749,7 @@ ASTLoweringType::visit (AST::TraitObjectTypeOneBound &type) void ASTLoweringType::visit (AST::TraitObjectType &type) { - std::vector<std::unique_ptr<HIR::TypeParamBound> > bounds; + std::vector<std::unique_ptr<HIR::TypeParamBound>> bounds; for (auto &bound : type.get_type_param_bounds ()) { @@ -915,7 +916,7 @@ std::unique_ptr<HIR::TuplePatternItems> ASTLoweringBase::lower_tuple_pattern_multiple ( AST::TuplePatternItemsMultiple &pattern) { - std::vector<std::unique_ptr<HIR::Pattern> > patterns; + std::vector<std::unique_ptr<HIR::Pattern>> patterns; for (auto &p : pattern.get_patterns ()) { HIR::Pattern *translated = ASTLoweringPattern::translate (p.get ()); @@ -930,8 +931,8 @@ std::unique_ptr<TuplePatternItems> ASTLoweringBase::lower_tuple_pattern_ranged ( AST::TuplePatternItemsRanged &pattern) { - std::vector<std::unique_ptr<HIR::Pattern> > lower_patterns; - std::vector<std::unique_ptr<HIR::Pattern> > upper_patterns; + std::vector<std::unique_ptr<HIR::Pattern>> lower_patterns; + std::vector<std::unique_ptr<HIR::Pattern>> upper_patterns; for (auto &p : pattern.get_lower_patterns ()) { @@ -1030,5 +1031,50 @@ ASTLoweringBase::lower_literal (const AST::Literal &literal) return HIR::Literal (literal.as_string (), type, literal.get_type_hint ()); } +HIR::ExternBlock * +ASTLoweringBase::lower_extern_block (AST::ExternBlock &extern_block) +{ + HIR::Visibility vis = translate_visibility (extern_block.get_visibility ()); + + std::vector<std::unique_ptr<HIR::ExternalItem>> extern_items; + for (auto &item : extern_block.get_extern_items ()) + { + if (item->is_marked_for_strip ()) + continue; + + HIR::ExternalItem *lowered + = ASTLoweringExternItem::translate (item.get ()); + extern_items.push_back (std::unique_ptr<HIR::ExternalItem> (lowered)); + } + + ABI abi = ABI::RUST; + if (extern_block.has_abi ()) + { + const std::string &extern_abi = extern_block.get_abi (); + abi = get_abi_from_string (extern_abi); + if (abi == ABI::UNKNOWN) + rust_error_at (extern_block.get_locus (), "unknown ABI option"); + } + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, extern_block.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + HIR::ExternBlock *hir_extern_block + = new HIR::ExternBlock (mapping, abi, std::move (extern_items), + std::move (vis), extern_block.get_inner_attrs (), + extern_block.get_outer_attrs (), + extern_block.get_locus ()); + + mappings->insert_defid_mapping (mapping.get_defid (), hir_extern_block); + mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (), + hir_extern_block); + mappings->insert_location (crate_num, mapping.get_hirid (), + extern_block.get_locus ()); + + return hir_extern_block; +} + } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h index 7e3eee1..aedec50 100644 --- a/gcc/rust/hir/rust-ast-lower-base.h +++ b/gcc/rust/hir/rust-ast-lower-base.h @@ -286,6 +286,8 @@ protected: lower_range_pattern_bound (AST::RangePatternBound *bound); HIR::Literal lower_literal (const AST::Literal &literal); + + HIR::ExternBlock *lower_extern_block (AST::ExternBlock &extern_block); }; } // namespace HIR diff --git a/gcc/rust/hir/rust-ast-lower-item.cc b/gcc/rust/hir/rust-ast-lower-item.cc index 5883338..5ab4dae 100644 --- a/gcc/rust/hir/rust-ast-lower-item.cc +++ b/gcc/rust/hir/rust-ast-lower-item.cc @@ -752,46 +752,7 @@ ASTLoweringItem::visit (AST::TraitImpl &impl_block) void ASTLoweringItem::visit (AST::ExternBlock &extern_block) { - HIR::Visibility vis = translate_visibility (extern_block.get_visibility ()); - - std::vector<std::unique_ptr<HIR::ExternalItem>> extern_items; - for (auto &item : extern_block.get_extern_items ()) - { - if (item->is_marked_for_strip ()) - continue; - - HIR::ExternalItem *lowered - = ASTLoweringExternItem::translate (item.get ()); - extern_items.push_back (std::unique_ptr<HIR::ExternalItem> (lowered)); - } - - ABI abi = ABI::RUST; - if (extern_block.has_abi ()) - { - const std::string &extern_abi = extern_block.get_abi (); - abi = get_abi_from_string (extern_abi); - if (abi == ABI::UNKNOWN) - rust_error_at (extern_block.get_locus (), "unknown ABI option"); - } - - auto crate_num = mappings->get_current_crate (); - Analysis::NodeMapping mapping (crate_num, extern_block.get_node_id (), - mappings->get_next_hir_id (crate_num), - mappings->get_next_localdef_id (crate_num)); - - HIR::ExternBlock *hir_extern_block - = new HIR::ExternBlock (mapping, abi, std::move (extern_items), - std::move (vis), extern_block.get_inner_attrs (), - extern_block.get_outer_attrs (), - extern_block.get_locus ()); - - translated = hir_extern_block; - - mappings->insert_defid_mapping (mapping.get_defid (), translated); - mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (), - translated); - mappings->insert_location (crate_num, mapping.get_hirid (), - extern_block.get_locus ()); + translated = lower_extern_block (extern_block); } HIR::SimplePath diff --git a/gcc/rust/hir/rust-ast-lower-stmt.h b/gcc/rust/hir/rust-ast-lower-stmt.h index 3ce77b4..199d146 100644 --- a/gcc/rust/hir/rust-ast-lower-stmt.h +++ b/gcc/rust/hir/rust-ast-lower-stmt.h @@ -437,6 +437,11 @@ public: translated = fn; } + void visit (AST::ExternBlock &extern_block) override + { + translated = lower_extern_block (extern_block); + } + private: ASTLoweringStmt () : translated (nullptr), terminated (false) {} diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.cc b/gcc/rust/resolve/rust-ast-resolve-stmt.cc new file mode 100644 index 0000000..6fc929f --- /dev/null +++ b/gcc/rust/resolve/rust-ast-resolve-stmt.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2020-2022 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-item.h" +#include "rust-ast-resolve-stmt.h" + +namespace Rust { +namespace Resolver { + +void +ResolveStmt::visit (AST::ExternBlock &extern_block) +{ + resolve_visibility (extern_block.get_visibility ()); + for (auto &item : extern_block.get_extern_items ()) + { + ResolveToplevelExternItem::go (item.get (), + CanonicalPath::create_empty ()); + ResolveExternItem::go (item.get ()); + } +} + +} // namespace Resolver +} // namespace Rust diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h index 3afed53..c8d42bc 100644 --- a/gcc/rust/resolve/rust-ast-resolve-stmt.h +++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h @@ -406,6 +406,8 @@ public: resolver->get_label_scope ().pop (); } + void visit (AST::ExternBlock &extern_block) override; + private: ResolveStmt (NodeId parent, const CanonicalPath &prefix, const CanonicalPath &canonical_prefix, diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h index 2f14966..b0ffd2a 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h +++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h @@ -24,6 +24,7 @@ #include "rust-hir-type-check-type.h" #include "rust-hir-type-check-expr.h" #include "rust-hir-type-check-enumitem.h" +#include "rust-hir-type-check-implitem.h" namespace Rust { namespace Resolver { @@ -56,6 +57,14 @@ public: = TyTy::TupleType::get_unit_type (stmt.get_mappings ().get_hirid ()); } + void visit (HIR::ExternBlock &extern_block) override + { + for (auto &item : extern_block.get_extern_items ()) + { + TypeCheckTopLevelExternItem::Resolve (item.get (), extern_block); + } + } + void visit (HIR::ConstantItem &constant) override { TyTy::BaseType *type = TypeCheckType::Resolve (constant.get_type ()); diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc index ee66638..60531c0 100644 --- a/gcc/rust/typecheck/rust-hir-type-check.cc +++ b/gcc/rust/typecheck/rust-hir-type-check.cc @@ -90,12 +90,7 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr) if (!s->is_item ()) continue; - auto resolved = TypeCheckStmt::Resolve (s.get (), inside_loop); - if (resolved == nullptr) - { - rust_error_at (s->get_locus (), "failure to resolve type"); - return; - } + TypeCheckStmt::Resolve (s.get (), inside_loop); } for (auto &s : expr.get_statements ()) diff --git a/gcc/testsuite/rust/execute/torture/issue-976.rs b/gcc/testsuite/rust/execute/torture/issue-976.rs new file mode 100644 index 0000000..42cf596 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-976.rs @@ -0,0 +1,14 @@ +/* { dg-output "hi" } */ +fn main() -> i32 { + { + extern "C" { + fn puts(s: *const i8); + } + + unsafe { + puts("hi\0" as *const str as *const i8); + } + } + + 0 +} |