Skip to content

Add name-resolution and HIR lowering for extern blocks #597

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions gcc/rust/ast/rust-ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -1364,6 +1364,8 @@ class TraitImplItem
class ExternalItem
{
public:
ExternalItem () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}

virtual ~ExternalItem () {}

// Unique pointer custom clone function
Expand All @@ -1379,9 +1381,13 @@ class ExternalItem
virtual void mark_for_strip () = 0;
virtual bool is_marked_for_strip () const = 0;

NodeId get_node_id () const { return node_id; }

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

NodeId node_id;
};

/* Data structure to store the data used in macro invocations and macro
Expand Down Expand Up @@ -1513,36 +1519,36 @@ class MacroInvocationSemi : public MacroItem,
return new MacroInvocationSemi (*this);
}

/* Use covariance to implement clone function as returning this object rather
* than base */
/* Use covariance to implement clone function as returning this object
* rather than base */
MacroInvocationSemi *clone_item_impl () const final override
{
return clone_macro_invocation_semi_impl ();
}

/* Use covariance to implement clone function as returning this object rather
* than base */
/* Use covariance to implement clone function as returning this object
* rather than base */
MacroInvocationSemi *clone_inherent_impl_item_impl () const final override
{
return clone_macro_invocation_semi_impl ();
}

/* Use covariance to implement clone function as returning this object rather
* than base */
/* Use covariance to implement clone function as returning this object
* rather than base */
MacroInvocationSemi *clone_trait_impl_item_impl () const final override
{
return clone_macro_invocation_semi_impl ();
}

/* Use covariance to implement clone function as returning this object rather
* than base */
/* Use covariance to implement clone function as returning this object
* rather than base */
MacroInvocationSemi *clone_trait_item_impl () const final override
{
return clone_macro_invocation_semi_impl ();
}

/* Use covariance to implement clone function as returning this object rather
* than base */
/* Use covariance to implement clone function as returning this object
* rather than base */
MacroInvocationSemi *clone_external_item_impl () const final override
{
return clone_macro_invocation_semi_impl ();
Expand Down
35 changes: 28 additions & 7 deletions gcc/rust/ast/rust-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -3910,16 +3910,17 @@ class ExternalStaticItem : public ExternalItem
ExternalStaticItem (Identifier item_name, std::unique_ptr<Type> item_type,
bool is_mut, Visibility vis,
std::vector<Attribute> outer_attrs, Location locus)
: outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
item_name (std::move (item_name)), locus (locus), has_mut (is_mut),
item_type (std::move (item_type))
: ExternalItem (), outer_attrs (std::move (outer_attrs)),
visibility (std::move (vis)), item_name (std::move (item_name)),
locus (locus), has_mut (is_mut), item_type (std::move (item_type))
{}

// Copy constructor
ExternalStaticItem (ExternalStaticItem const &other)
: outer_attrs (other.outer_attrs), visibility (other.visibility),
item_name (other.item_name), locus (other.locus), has_mut (other.has_mut)
{
node_id = other.node_id;
// guard to prevent null dereference (only required if error state)
if (other.item_type != nullptr)
item_type = other.item_type->clone_type ();
Expand All @@ -3928,6 +3929,7 @@ class ExternalStaticItem : public ExternalItem
// Overloaded assignment operator to clone
ExternalStaticItem &operator= (ExternalStaticItem const &other)
{
node_id = other.node_id;
outer_attrs = other.outer_attrs;
visibility = other.visibility;
item_name = other.item_name;
Expand Down Expand Up @@ -3974,6 +3976,10 @@ class ExternalStaticItem : public ExternalItem
return item_type;
}

Identifier get_identifier () const { return item_name; }

bool is_mut () const { return has_mut; }

protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
Expand All @@ -3997,6 +4003,8 @@ struct NamedFunctionParam
// seemingly new since writing this node
std::vector<Attribute> outer_attrs;

NodeId node_id;

public:
/* Returns whether the named function parameter has a name (i.e. name is not
* '_'). */
Expand All @@ -4011,6 +4019,8 @@ struct NamedFunctionParam
return param_type == nullptr;
}

std::string get_name () const { return name; }

// Creates an error state named function parameter.
static NamedFunctionParam create_error ()
{
Expand All @@ -4020,13 +4030,15 @@ struct NamedFunctionParam
NamedFunctionParam (std::string name, std::unique_ptr<Type> param_type,
std::vector<Attribute> outer_attrs)
: name (std::move (name)), param_type (std::move (param_type)),
outer_attrs (std::move (outer_attrs))
outer_attrs (std::move (outer_attrs)),
node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}

// Copy constructor
NamedFunctionParam (NamedFunctionParam const &other)
: name (other.name), outer_attrs (other.outer_attrs)
{
node_id = other.node_id;
// guard to prevent null dereference (only required if error state)
if (other.param_type != nullptr)
param_type = other.param_type->clone_type ();
Expand All @@ -4037,6 +4049,7 @@ struct NamedFunctionParam
// Overloaded assignment operator to clone
NamedFunctionParam &operator= (NamedFunctionParam const &other)
{
node_id = other.node_id;
name = other.name;
// has_name = other.has_name;
outer_attrs = other.outer_attrs;
Expand Down Expand Up @@ -4070,6 +4083,8 @@ struct NamedFunctionParam
rust_assert (param_type != nullptr);
return param_type;
}

NodeId get_node_id () const { return node_id; }
};

// A function item used in an extern block
Expand Down Expand Up @@ -4133,9 +4148,9 @@ class ExternalFunctionItem : public ExternalItem
std::vector<NamedFunctionParam> function_params, bool has_variadics,
std::vector<Attribute> variadic_outer_attrs, Visibility vis,
std::vector<Attribute> outer_attrs, Location locus)
: outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
item_name (std::move (item_name)), locus (locus),
generic_params (std::move (generic_params)),
: ExternalItem (), outer_attrs (std::move (outer_attrs)),
visibility (std::move (vis)), item_name (std::move (item_name)),
locus (locus), generic_params (std::move (generic_params)),
return_type (std::move (return_type)),
where_clause (std::move (where_clause)),
function_params (std::move (function_params)),
Expand All @@ -4155,6 +4170,7 @@ class ExternalFunctionItem : public ExternalItem
has_variadics (other.has_variadics),
variadic_outer_attrs (other.variadic_outer_attrs)
{
node_id = other.node_id;
// guard to prevent null pointer dereference
if (other.return_type != nullptr)
return_type = other.return_type->clone_type ();
Expand All @@ -4175,6 +4191,7 @@ class ExternalFunctionItem : public ExternalItem
function_params = other.function_params;
has_variadics = other.has_variadics;
variadic_outer_attrs = other.variadic_outer_attrs;
node_id = other.node_id;

// guard to prevent null pointer dereference
if (other.return_type != nullptr)
Expand Down Expand Up @@ -4237,6 +4254,8 @@ class ExternalFunctionItem : public ExternalItem
return return_type;
}

Identifier get_identifier () const { return item_name; };

protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
Expand Down Expand Up @@ -4275,6 +4294,8 @@ class ExternBlock : public VisItem
// Returns whether extern block has ABI name.
bool has_abi () const { return !abi.empty (); }

std::string get_abi () const { return abi; }

ExternBlock (std::string abi,
std::vector<std::unique_ptr<ExternalItem> > extern_items,
Visibility vis, std::vector<Attribute> inner_attrs,
Expand Down
121 changes: 121 additions & 0 deletions gcc/rust/hir/rust-ast-lower-extern.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// 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_AST_LOWER_EXTERN_ITEM
#define RUST_AST_LOWER_EXTERN_ITEM

#include "rust-ast-lower-base.h"
#include "rust-ast-lower-type.h"

namespace Rust {
namespace HIR {

class ASTLoweringExternItem : public ASTLoweringBase
{
using Rust::HIR::ASTLoweringBase::visit;

public:
static HIR::ExternalItem *translate (AST::ExternalItem *item)
{
ASTLoweringExternItem resolver;
item->accept_vis (resolver);
return resolver.translated;
}

void visit (AST::ExternalStaticItem &item) override
{
HIR::Visibility vis = HIR::Visibility::create_public ();
HIR::Type *static_type
= ASTLoweringType::translate (item.get_type ().get ());

auto crate_num = mappings->get_current_crate ();
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 (),
std::unique_ptr<HIR::Type> (static_type),
item.is_mut (), std::move (vis),
item.get_outer_attrs (),
item.get_locus ());

translated = static_item;
}

void visit (AST::ExternalFunctionItem &function) override
{
std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
HIR::WhereClause where_clause (std::move (where_clause_items));
HIR::Visibility vis = HIR::Visibility::create_public ();

std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
if (function.has_generics ())
generic_params = lower_generic_params (function.get_generic_params ());

HIR::Type *return_type
= function.has_return_type ()
? ASTLoweringType::translate (function.get_return_type ().get ())
: nullptr;

std::vector<HIR::NamedFunctionParam> function_params;
for (auto &param : function.get_function_params ())
{
HIR::Type *param_type
= ASTLoweringType::translate (param.get_type ().get ());
Identifier param_name = param.get_name ();

auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (
crate_num));

function_params.push_back (
HIR::NamedFunctionParam (mapping, param_name,
std::unique_ptr<HIR::Type> (param_type)));
}

auto crate_num = mappings->get_current_crate ();
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),
std::unique_ptr<HIR::Type> (return_type), std::move (where_clause),
std::move (function_params), function.is_variadic (), std::move (vis),
function.get_outer_attrs (), function.get_locus ());

translated = function_item;
}

private:
ASTLoweringExternItem () : translated (nullptr) {}

HIR::ExternalItem *translated;
};

} // namespace HIR
} // namespace Rust

#endif // RUST_AST_LOWER_ITEM
32 changes: 32 additions & 0 deletions gcc/rust/hir/rust-ast-lower-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "rust-ast-lower-expr.h"
#include "rust-ast-lower-pattern.h"
#include "rust-ast-lower-block.h"
#include "rust-ast-lower-extern.h"

namespace Rust {
namespace HIR {
Expand Down Expand Up @@ -553,6 +554,37 @@ class ASTLoweringItem : public ASTLoweringBase
}
}

void visit (AST::ExternBlock &extern_block) override
{
HIR::Visibility vis = HIR::Visibility::create_public ();

std::vector<std::unique_ptr<HIR::ExternalItem> > extern_items;
for (auto &item : extern_block.get_extern_items ())
{
HIR::ExternalItem *lowered
= ASTLoweringExternItem::translate (item.get ());
extern_items.push_back (std::unique_ptr<HIR::ExternalItem> (lowered));
}

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));

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),
extern_block.get_inner_attrs (),
extern_block.get_outer_attrs (),
extern_block.get_locus ());

translated = hir_extern_block;
}

private:
ASTLoweringItem () : translated (nullptr) {}

Expand Down
5 changes: 3 additions & 2 deletions gcc/rust/hir/tree/rust-hir-full-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3399,8 +3399,9 @@ ExternalFunctionItem::as_string () const
}
}

// add type on new line
str += "\n (return) Type: " + return_type->as_string ();
// add type on new line)
str += "\n (return) Type: "
+ (has_return_type () ? return_type->as_string () : "()");

// where clause
str += "\n Where clause: ";
Expand Down
Loading