Skip to content

Commit

Permalink
Merge #598
Browse files Browse the repository at this point in the history
598: Hello world r=philberty a=philberty

```rust
extern "C" {
    fn puts(s: *const i8);
}

fn main() {
    unsafe {
        let a = "Hello World\0";
        let b = a as *const str;
        let c = b as *const i8;
        puts(c);
    }
}
```

Fixes #421

Co-authored-by: Philip Herron <[email protected]>
  • Loading branch information
bors[bot] and philberty authored Jul 27, 2021
2 parents 9526e6d + 7f8adcc commit f76ddb4
Show file tree
Hide file tree
Showing 19 changed files with 513 additions and 46 deletions.
11 changes: 8 additions & 3 deletions gcc/rust/backend/rust-compile-context.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,14 @@ class TyTyResolveCompile : public TyTy::TyVisitor
parameters.push_back (compiled_param);
}

translated = ctx->get_backend ()->function_type (
receiver, parameters, results, NULL,
ctx->get_mappings ()->lookup_location (type.get_ref ()));
if (!type.is_varadic ())
translated = ctx->get_backend ()->function_type (
receiver, parameters, results, NULL,
ctx->get_mappings ()->lookup_location (type.get_ref ()));
else
translated = ctx->get_backend ()->function_type_varadic (
receiver, parameters, results, NULL,
ctx->get_mappings ()->lookup_location (type.get_ref ()));
}

void visit (TyTy::FnPtr &type) override
Expand Down
148 changes: 148 additions & 0 deletions gcc/rust/backend/rust-compile-extern.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// 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_COMPILE_EXTERN_ITEM
#define RUST_COMPILE_EXTERN_ITEM

#include "rust-compile-base.h"
#include "rust-compile-tyty.h"
#include "rust-compile-implitem.h"
#include "rust-compile-var-decl.h"
#include "rust-compile-stmt.h"
#include "rust-compile-expr.h"
#include "rust-compile-fnparam.h"

namespace Rust {
namespace Compile {

class CompileExternItem : public HIRCompileBase
{
using Rust::Compile::HIRCompileBase::visit;

public:
static void compile (HIR::ExternalItem *item, Context *ctx,
bool compile_fns = true,
TyTy::BaseType *concrete = nullptr)
{
CompileExternItem compiler (ctx, compile_fns, concrete);
item->accept_vis (compiler);
}

void visit (HIR::ExternalStaticItem &item) override
{
TyTy::BaseType *resolved_type = nullptr;
bool ok = ctx->get_tyctx ()->lookup_type (item.get_mappings ().get_hirid (),
&resolved_type);
rust_assert (ok);

std::string name = item.get_item_name ();
// FIXME this is assuming C ABI
std::string asm_name = name;

Btype *type = TyTyResolveCompile::compile (ctx, resolved_type);
bool is_external = true;
bool is_hidden = false;
bool in_unique_section = false;

Bvariable *static_global
= ctx->get_backend ()->global_variable (name, asm_name, type, is_external,
is_hidden, in_unique_section,
item.get_locus ());
ctx->insert_var_decl (item.get_mappings ().get_hirid (), static_global);
ctx->push_var (static_global);
}

void visit (HIR::ExternalFunctionItem &function) override
{
if (!compile_fns)
return;

TyTy::BaseType *fntype_tyty;
if (!ctx->get_tyctx ()->lookup_type (function.get_mappings ().get_hirid (),
&fntype_tyty))
{
rust_fatal_error (function.get_locus (),
"failed to lookup function type");
return;
}

rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
if (fntype->has_subsititions_defined ())
{
// we cant do anything for this only when it is used and a concrete type
// is given
if (concrete == nullptr)
return;
else
{
rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
fntype = static_cast<TyTy::FnType *> (concrete);
}
}

// 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.
Bfunction *lookup = nullptr;
if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup, fntype))
{
// has this been added to the list then it must be finished
if (ctx->function_completed (lookup))
{
Bfunction *dummy = nullptr;
if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
ctx->insert_function_decl (fntype->get_ty_ref (), lookup, fntype);

return;
}
}

if (fntype->has_subsititions_defined ())
{
// override the Hir Lookups for the substituions in this context
fntype->override_context ();
}

::Btype *compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);

const unsigned int flags
= Backend::function_is_declaration | Backend::function_is_visible;

std::string ir_symbol_name = function.get_item_name ();
// FIXME this assumes C ABI
std::string asm_name = function.get_item_name ();

Bfunction *fndecl
= ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
asm_name, flags, function.get_locus ());
ctx->insert_function_decl (fntype->get_ty_ref (), fndecl, fntype);
}

private:
CompileExternItem (Context *ctx, bool compile_fns, TyTy::BaseType *concrete)
: HIRCompileBase (ctx), compile_fns (compile_fns), concrete (concrete)
{}

bool compile_fns;
TyTy::BaseType *concrete;
};

} // namespace Compile
} // namespace Rust

#endif // RUST_COMPILE_EXTERN_ITEM
9 changes: 9 additions & 0 deletions gcc/rust/backend/rust-compile-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "rust-compile-stmt.h"
#include "rust-compile-expr.h"
#include "rust-compile-fnparam.h"
#include "rust-compile-extern.h"

namespace Rust {
namespace Compile {
Expand Down Expand Up @@ -274,6 +275,14 @@ class CompileItem : public HIRCompileBase
compile_fns);
}

void visit (HIR::ExternBlock &extern_block) override
{
for (auto &item : extern_block.get_extern_items ())
{
CompileExternItem::compile (item.get (), ctx, compile_fns, concrete);
}
}

private:
CompileItem (Context *ctx, bool compile_fns, TyTy::BaseType *concrete)
: HIRCompileBase (ctx), compile_fns (compile_fns), concrete (concrete)
Expand Down
12 changes: 9 additions & 3 deletions gcc/rust/backend/rust-compile-tyty.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,15 @@ class TyTyCompile : public TyTy::TyVisitor
parameters.push_back (compiled_param);
}

translated
= backend->function_type (receiver, parameters, results, NULL,
mappings->lookup_location (type.get_ref ()));
if (!type.is_varadic ())
translated
= backend->function_type (receiver, parameters, results, NULL,
mappings->lookup_location (type.get_ref ()));
else
translated
= backend->function_type_varadic (receiver, parameters, results, NULL,
mappings->lookup_location (
type.get_ref ()));
}

void visit (TyTy::BoolType &) override
Expand Down
14 changes: 10 additions & 4 deletions gcc/rust/hir/rust-ast-lower-extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ class ASTLoweringExternItem : public ASTLoweringBase
Analysis::NodeMapping mapping (crate_num, item.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
mappings->insert_location (crate_num, mapping.get_hirid (),
item.get_locus ());

HIR::ExternalStaticItem *static_item
= new HIR::ExternalStaticItem (mapping, item.get_identifier (),
Expand All @@ -58,6 +56,11 @@ class ASTLoweringExternItem : public ASTLoweringBase
item.get_locus ());

translated = static_item;

mappings->insert_hir_extern_item (crate_num, mapping.get_hirid (),
translated);
mappings->insert_location (crate_num, mapping.get_hirid (),
item.get_locus ());
}

void visit (AST::ExternalFunctionItem &function) override
Expand Down Expand Up @@ -97,8 +100,6 @@ class ASTLoweringExternItem : public ASTLoweringBase
Analysis::NodeMapping mapping (crate_num, function.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
mappings->insert_location (crate_num, mapping.get_hirid (),
function.get_locus ());

HIR::ExternalFunctionItem *function_item = new HIR::ExternalFunctionItem (
mapping, function.get_identifier (), std::move (generic_params),
Expand All @@ -107,6 +108,11 @@ class ASTLoweringExternItem : public ASTLoweringBase
function.get_outer_attrs (), function.get_locus ());

translated = function_item;

mappings->insert_hir_extern_item (crate_num, mapping.get_hirid (),
translated);
mappings->insert_location (crate_num, mapping.get_hirid (),
function.get_locus ());
}

private:
Expand Down
10 changes: 6 additions & 4 deletions gcc/rust/hir/rust-ast-lower-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -571,10 +571,6 @@ class ASTLoweringItem : public ASTLoweringBase
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));

mappings->insert_defid_mapping (mapping.get_defid (), translated);
mappings->insert_location (crate_num, mapping.get_hirid (),
extern_block.get_locus ());

HIR::ExternBlock *hir_extern_block
= new HIR::ExternBlock (mapping, extern_block.get_abi (),
std::move (extern_items), std::move (vis),
Expand All @@ -583,6 +579,12 @@ class ASTLoweringItem : public ASTLoweringBase
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 ());
}

private:
Expand Down
32 changes: 29 additions & 3 deletions gcc/rust/hir/tree/rust-hir-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -2713,6 +2713,8 @@ class ExternalItem

Analysis::NodeMapping get_mappings () const { return mappings; }

Identifier get_item_name () const { return item_name; }

protected:
ExternalItem (Analysis::NodeMapping mappings, Identifier item_name,
Visibility vis, AST::AttrVec outer_attrs, Location locus)
Expand Down Expand Up @@ -2746,9 +2748,6 @@ class ExternalItem

// Clone function implementation as pure virtual method
virtual ExternalItem *clone_external_item_impl () const = 0;

// possibly make this public if required
std::string get_item_name () const { return item_name; }
};

// A static item used in an extern block
Expand Down Expand Up @@ -2790,6 +2789,8 @@ class ExternalStaticItem : public ExternalItem

void accept_vis (HIRVisitor &vis) override;

std::unique_ptr<Type> &get_item_type () { return item_type; }

protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
Expand Down Expand Up @@ -2840,6 +2841,12 @@ struct NamedFunctionParam
NamedFunctionParam &operator= (NamedFunctionParam &&other) = default;

std::string as_string () const;

Identifier get_param_name () const { return name; }

std::unique_ptr<Type> &get_type () { return param_type; }

Analysis::NodeMapping get_mappings () const { return mappings; }
};

// A function item used in an extern block
Expand Down Expand Up @@ -2920,6 +2927,20 @@ class ExternalFunctionItem : public ExternalItem

void accept_vis (HIRVisitor &vis) override;

std::vector<std::unique_ptr<GenericParam> > &get_generic_params ()
{
return generic_params;
}

std::unique_ptr<Type> &get_return_type () { return return_type; }

std::vector<NamedFunctionParam> &get_function_params ()
{
return function_params;
}

bool is_variadic () const { return has_variadics; }

protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
Expand Down Expand Up @@ -2999,6 +3020,11 @@ class ExternBlock : public VisItem

void accept_vis (HIRVisitor &vis) override;

std::vector<std::unique_ptr<ExternalItem> > &get_extern_items ()
{
return extern_items;
}

protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
Expand Down
2 changes: 1 addition & 1 deletion gcc/rust/resolve/rust-ast-resolve-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ class ResolveExternItem : public ResolverBase

private:
ResolveExternItem () : ResolverBase (UNKNOWN_NODEID) {}
}; // namespace Resolver
};

} // namespace Resolver
} // namespace Rust
Expand Down
4 changes: 3 additions & 1 deletion gcc/rust/resolve/rust-ast-resolve.cc
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,9 @@ ResolveItem::resolve_impl_item (AST::InherentImplItem *item,

void
ResolveItem::resolve_extern_item (AST::ExternalItem *item)
{}
{
ResolveExternItem::go (item);
}

} // namespace Resolver
} // namespace Rust
7 changes: 7 additions & 0 deletions gcc/rust/rust-backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ class Backend
Btype *result_struct, Location location)
= 0;

virtual Btype *
function_type_varadic (const Btyped_identifier &receiver,
const std::vector<Btyped_identifier> &parameters,
const std::vector<Btyped_identifier> &results,
Btype *result_struct, Location location)
= 0;

virtual Btype *function_ptr_type (Btype *result,
const std::vector<Btype *> &praameters,
Location location)
Expand Down
Loading

0 comments on commit f76ddb4

Please sign in to comment.