public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Support extern-blocks defined within blocks
@ 2022-06-08 12:47 Thomas Schwinge
0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 12:47 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:4a4206c017654af7a3468690e4e21fdaf86bcb5c
commit 4a4206c017654af7a3468690e4e21fdaf86bcb5c
Author: Philip Herron <philip.herron@embecosm.com>
Date: Mon May 16 17:09:45 2022 +0100
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
Diff:
---
gcc/rust/Make-lang.in | 1 +
gcc/rust/backend/rust-compile-base.cc | 8 ++-
gcc/rust/backend/rust-compile-extern.h | 27 ++++++++--
gcc/rust/backend/rust-compile-resolve-path.cc | 16 +++++-
gcc/rust/hir/rust-ast-lower-base.cc | 68 +++++++++++++++++++++----
gcc/rust/hir/rust-ast-lower-base.h | 2 +
gcc/rust/hir/rust-ast-lower-item.cc | 41 +--------------
gcc/rust/hir/rust-ast-lower-stmt.h | 5 ++
gcc/rust/resolve/rust-ast-resolve-stmt.cc | 38 ++++++++++++++
gcc/rust/resolve/rust-ast-resolve-stmt.h | 2 +
gcc/rust/typecheck/rust-hir-type-check-stmt.h | 9 ++++
gcc/rust/typecheck/rust-hir-type-check.cc | 7 +--
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 738cfdf20ef..2d701ea25ee 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 6773ac61382..7b0a375439c 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 1987805146d..c24437deb2f 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 bd44bf45791..ca96a277ea8 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 7afe75cd0ca..a4821329148 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 7e3eee134a1..aedec50109e 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 588333817ef..5ab4dae5dab 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 3ce77b4d9ca..199d146f5d5 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 00000000000..6fc929f3e43
--- /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 3afed532afa..c8d42bcc7ca 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 2f14966ed66..b0ffd2a2157 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 ee6663877a5..60531c0933d 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 00000000000..42cf596fb7d
--- /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
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-06-08 12:47 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 12:47 [gcc/devel/rust/master] Support extern-blocks defined within blocks Thomas Schwinge
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).