Skip to content

Commit 5f238bc

Browse files
committed
Add name-resolution and HIR lowering for extern blocks
This is the initial patch to do the ground work to support extern blocks. Type resolution and Generic output still needs to be done to actually support extern blocks. Addresses #421
1 parent 5b3909d commit 5f238bc

10 files changed

+345
-56
lines changed

gcc/rust/ast/rust-ast.h

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,8 @@ class TraitImplItem
13641364
class ExternalItem
13651365
{
13661366
public:
1367+
ExternalItem () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) {}
1368+
13671369
virtual ~ExternalItem () {}
13681370

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

1384+
NodeId get_node_id () const { return node_id; }
1385+
13821386
protected:
13831387
// Clone function implementation as pure virtual method
13841388
virtual ExternalItem *clone_external_item_impl () const = 0;
1389+
1390+
NodeId node_id;
13851391
};
13861392

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

1516-
/* Use covariance to implement clone function as returning this object rather
1517-
* than base */
1522+
/* Use covariance to implement clone function as returning this object
1523+
* rather than base */
15181524
MacroInvocationSemi *clone_item_impl () const final override
15191525
{
15201526
return clone_macro_invocation_semi_impl ();
15211527
}
15221528

1523-
/* Use covariance to implement clone function as returning this object rather
1524-
* than base */
1529+
/* Use covariance to implement clone function as returning this object
1530+
* rather than base */
15251531
MacroInvocationSemi *clone_inherent_impl_item_impl () const final override
15261532
{
15271533
return clone_macro_invocation_semi_impl ();
15281534
}
15291535

1530-
/* Use covariance to implement clone function as returning this object rather
1531-
* than base */
1536+
/* Use covariance to implement clone function as returning this object
1537+
* rather than base */
15321538
MacroInvocationSemi *clone_trait_impl_item_impl () const final override
15331539
{
15341540
return clone_macro_invocation_semi_impl ();
15351541
}
15361542

1537-
/* Use covariance to implement clone function as returning this object rather
1538-
* than base */
1543+
/* Use covariance to implement clone function as returning this object
1544+
* rather than base */
15391545
MacroInvocationSemi *clone_trait_item_impl () const final override
15401546
{
15411547
return clone_macro_invocation_semi_impl ();
15421548
}
15431549

1544-
/* Use covariance to implement clone function as returning this object rather
1545-
* than base */
1550+
/* Use covariance to implement clone function as returning this object
1551+
* rather than base */
15461552
MacroInvocationSemi *clone_external_item_impl () const final override
15471553
{
15481554
return clone_macro_invocation_semi_impl ();

gcc/rust/ast/rust-item.h

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3910,16 +3910,17 @@ class ExternalStaticItem : public ExternalItem
39103910
ExternalStaticItem (Identifier item_name, std::unique_ptr<Type> item_type,
39113911
bool is_mut, Visibility vis,
39123912
std::vector<Attribute> outer_attrs, Location locus)
3913-
: outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
3914-
item_name (std::move (item_name)), locus (locus), has_mut (is_mut),
3915-
item_type (std::move (item_type))
3913+
: ExternalItem (), outer_attrs (std::move (outer_attrs)),
3914+
visibility (std::move (vis)), item_name (std::move (item_name)),
3915+
locus (locus), has_mut (is_mut), item_type (std::move (item_type))
39163916
{}
39173917

39183918
// Copy constructor
39193919
ExternalStaticItem (ExternalStaticItem const &other)
39203920
: outer_attrs (other.outer_attrs), visibility (other.visibility),
39213921
item_name (other.item_name), locus (other.locus), has_mut (other.has_mut)
39223922
{
3923+
node_id = other.node_id;
39233924
// guard to prevent null dereference (only required if error state)
39243925
if (other.item_type != nullptr)
39253926
item_type = other.item_type->clone_type ();
@@ -3928,6 +3929,7 @@ class ExternalStaticItem : public ExternalItem
39283929
// Overloaded assignment operator to clone
39293930
ExternalStaticItem &operator= (ExternalStaticItem const &other)
39303931
{
3932+
node_id = other.node_id;
39313933
outer_attrs = other.outer_attrs;
39323934
visibility = other.visibility;
39333935
item_name = other.item_name;
@@ -3974,6 +3976,10 @@ class ExternalStaticItem : public ExternalItem
39743976
return item_type;
39753977
}
39763978

3979+
Identifier get_identifier () const { return item_name; }
3980+
3981+
bool is_mut () const { return has_mut; }
3982+
39773983
protected:
39783984
/* Use covariance to implement clone function as returning this object
39793985
* rather than base */
@@ -3997,6 +4003,8 @@ struct NamedFunctionParam
39974003
// seemingly new since writing this node
39984004
std::vector<Attribute> outer_attrs;
39994005

4006+
NodeId node_id;
4007+
40004008
public:
40014009
/* Returns whether the named function parameter has a name (i.e. name is not
40024010
* '_'). */
@@ -4011,6 +4019,8 @@ struct NamedFunctionParam
40114019
return param_type == nullptr;
40124020
}
40134021

4022+
std::string get_name () const { return name; }
4023+
40144024
// Creates an error state named function parameter.
40154025
static NamedFunctionParam create_error ()
40164026
{
@@ -4020,13 +4030,15 @@ struct NamedFunctionParam
40204030
NamedFunctionParam (std::string name, std::unique_ptr<Type> param_type,
40214031
std::vector<Attribute> outer_attrs)
40224032
: name (std::move (name)), param_type (std::move (param_type)),
4023-
outer_attrs (std::move (outer_attrs))
4033+
outer_attrs (std::move (outer_attrs)),
4034+
node_id (Analysis::Mappings::get ()->get_next_node_id ())
40244035
{}
40254036

40264037
// Copy constructor
40274038
NamedFunctionParam (NamedFunctionParam const &other)
40284039
: name (other.name), outer_attrs (other.outer_attrs)
40294040
{
4041+
node_id = other.node_id;
40304042
// guard to prevent null dereference (only required if error state)
40314043
if (other.param_type != nullptr)
40324044
param_type = other.param_type->clone_type ();
@@ -4037,6 +4049,7 @@ struct NamedFunctionParam
40374049
// Overloaded assignment operator to clone
40384050
NamedFunctionParam &operator= (NamedFunctionParam const &other)
40394051
{
4052+
node_id = other.node_id;
40404053
name = other.name;
40414054
// has_name = other.has_name;
40424055
outer_attrs = other.outer_attrs;
@@ -4070,6 +4083,8 @@ struct NamedFunctionParam
40704083
rust_assert (param_type != nullptr);
40714084
return param_type;
40724085
}
4086+
4087+
NodeId get_node_id () const { return node_id; }
40734088
};
40744089

40754090
// A function item used in an extern block
@@ -4133,9 +4148,9 @@ class ExternalFunctionItem : public ExternalItem
41334148
std::vector<NamedFunctionParam> function_params, bool has_variadics,
41344149
std::vector<Attribute> variadic_outer_attrs, Visibility vis,
41354150
std::vector<Attribute> outer_attrs, Location locus)
4136-
: outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
4137-
item_name (std::move (item_name)), locus (locus),
4138-
generic_params (std::move (generic_params)),
4151+
: ExternalItem (), outer_attrs (std::move (outer_attrs)),
4152+
visibility (std::move (vis)), item_name (std::move (item_name)),
4153+
locus (locus), generic_params (std::move (generic_params)),
41394154
return_type (std::move (return_type)),
41404155
where_clause (std::move (where_clause)),
41414156
function_params (std::move (function_params)),
@@ -4155,6 +4170,7 @@ class ExternalFunctionItem : public ExternalItem
41554170
has_variadics (other.has_variadics),
41564171
variadic_outer_attrs (other.variadic_outer_attrs)
41574172
{
4173+
node_id = other.node_id;
41584174
// guard to prevent null pointer dereference
41594175
if (other.return_type != nullptr)
41604176
return_type = other.return_type->clone_type ();
@@ -4175,6 +4191,7 @@ class ExternalFunctionItem : public ExternalItem
41754191
function_params = other.function_params;
41764192
has_variadics = other.has_variadics;
41774193
variadic_outer_attrs = other.variadic_outer_attrs;
4194+
node_id = other.node_id;
41784195

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

4257+
Identifier get_identifier () const { return item_name; };
4258+
42404259
protected:
42414260
/* Use covariance to implement clone function as returning this object
42424261
* rather than base */
@@ -4275,6 +4294,8 @@ class ExternBlock : public VisItem
42754294
// Returns whether extern block has ABI name.
42764295
bool has_abi () const { return !abi.empty (); }
42774296

4297+
std::string get_abi () const { return abi; }
4298+
42784299
ExternBlock (std::string abi,
42794300
std::vector<std::unique_ptr<ExternalItem> > extern_items,
42804301
Visibility vis, std::vector<Attribute> inner_attrs,

gcc/rust/hir/rust-ast-lower-extern.h

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// Copyright (C) 2020 Free Software Foundation, Inc.
2+
3+
// This file is part of GCC.
4+
5+
// GCC is free software; you can redistribute it and/or modify it under
6+
// the terms of the GNU General Public License as published by the Free
7+
// Software Foundation; either version 3, or (at your option) any later
8+
// version.
9+
10+
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11+
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
// for more details.
14+
15+
// You should have received a copy of the GNU General Public License
16+
// along with GCC; see the file COPYING3. If not see
17+
// <http://www.gnu.org/licenses/>.
18+
19+
#ifndef RUST_AST_LOWER_EXTERN_ITEM
20+
#define RUST_AST_LOWER_EXTERN_ITEM
21+
22+
#include "rust-ast-lower-base.h"
23+
#include "rust-ast-lower-type.h"
24+
25+
namespace Rust {
26+
namespace HIR {
27+
28+
class ASTLoweringExternItem : public ASTLoweringBase
29+
{
30+
using Rust::HIR::ASTLoweringBase::visit;
31+
32+
public:
33+
static HIR::ExternalItem *translate (AST::ExternalItem *item)
34+
{
35+
ASTLoweringExternItem resolver;
36+
item->accept_vis (resolver);
37+
return resolver.translated;
38+
}
39+
40+
void visit (AST::ExternalStaticItem &item) override
41+
{
42+
HIR::Visibility vis = HIR::Visibility::create_public ();
43+
HIR::Type *static_type
44+
= ASTLoweringType::translate (item.get_type ().get ());
45+
46+
auto crate_num = mappings->get_current_crate ();
47+
Analysis::NodeMapping mapping (crate_num, item.get_node_id (),
48+
mappings->get_next_hir_id (crate_num),
49+
mappings->get_next_localdef_id (crate_num));
50+
mappings->insert_location (crate_num, mapping.get_hirid (),
51+
item.get_locus ());
52+
53+
HIR::ExternalStaticItem *static_item
54+
= new HIR::ExternalStaticItem (mapping, item.get_identifier (),
55+
std::unique_ptr<HIR::Type> (static_type),
56+
item.is_mut (), std::move (vis),
57+
item.get_outer_attrs (),
58+
item.get_locus ());
59+
60+
translated = static_item;
61+
}
62+
63+
void visit (AST::ExternalFunctionItem &function) override
64+
{
65+
std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
66+
HIR::WhereClause where_clause (std::move (where_clause_items));
67+
HIR::Visibility vis = HIR::Visibility::create_public ();
68+
69+
std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
70+
if (function.has_generics ())
71+
generic_params = lower_generic_params (function.get_generic_params ());
72+
73+
HIR::Type *return_type
74+
= function.has_return_type ()
75+
? ASTLoweringType::translate (function.get_return_type ().get ())
76+
: nullptr;
77+
78+
std::vector<HIR::NamedFunctionParam> function_params;
79+
for (auto &param : function.get_function_params ())
80+
{
81+
HIR::Type *param_type
82+
= ASTLoweringType::translate (param.get_type ().get ());
83+
Identifier param_name = param.get_name ();
84+
85+
auto crate_num = mappings->get_current_crate ();
86+
Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
87+
mappings->get_next_hir_id (crate_num),
88+
mappings->get_next_localdef_id (
89+
crate_num));
90+
91+
function_params.push_back (
92+
HIR::NamedFunctionParam (mapping, param_name,
93+
std::unique_ptr<HIR::Type> (param_type)));
94+
}
95+
96+
auto crate_num = mappings->get_current_crate ();
97+
Analysis::NodeMapping mapping (crate_num, function.get_node_id (),
98+
mappings->get_next_hir_id (crate_num),
99+
mappings->get_next_localdef_id (crate_num));
100+
mappings->insert_location (crate_num, mapping.get_hirid (),
101+
function.get_locus ());
102+
103+
HIR::ExternalFunctionItem *function_item = new HIR::ExternalFunctionItem (
104+
mapping, function.get_identifier (), std::move (generic_params),
105+
std::unique_ptr<HIR::Type> (return_type), std::move (where_clause),
106+
std::move (function_params), function.is_variadic (), std::move (vis),
107+
function.get_outer_attrs (), function.get_locus ());
108+
109+
translated = function_item;
110+
}
111+
112+
private:
113+
ASTLoweringExternItem () : translated (nullptr) {}
114+
115+
HIR::ExternalItem *translated;
116+
};
117+
118+
} // namespace HIR
119+
} // namespace Rust
120+
121+
#endif // RUST_AST_LOWER_ITEM

gcc/rust/hir/rust-ast-lower-item.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "rust-ast-lower-expr.h"
2929
#include "rust-ast-lower-pattern.h"
3030
#include "rust-ast-lower-block.h"
31+
#include "rust-ast-lower-extern.h"
3132

3233
namespace Rust {
3334
namespace HIR {
@@ -553,6 +554,37 @@ class ASTLoweringItem : public ASTLoweringBase
553554
}
554555
}
555556

557+
void visit (AST::ExternBlock &extern_block) override
558+
{
559+
HIR::Visibility vis = HIR::Visibility::create_public ();
560+
561+
std::vector<std::unique_ptr<HIR::ExternalItem> > extern_items;
562+
for (auto &item : extern_block.get_extern_items ())
563+
{
564+
HIR::ExternalItem *lowered
565+
= ASTLoweringExternItem::translate (item.get ());
566+
extern_items.push_back (std::unique_ptr<HIR::ExternalItem> (lowered));
567+
}
568+
569+
auto crate_num = mappings->get_current_crate ();
570+
Analysis::NodeMapping mapping (crate_num, extern_block.get_node_id (),
571+
mappings->get_next_hir_id (crate_num),
572+
mappings->get_next_localdef_id (crate_num));
573+
574+
mappings->insert_defid_mapping (mapping.get_defid (), translated);
575+
mappings->insert_location (crate_num, mapping.get_hirid (),
576+
extern_block.get_locus ());
577+
578+
HIR::ExternBlock *hir_extern_block
579+
= new HIR::ExternBlock (mapping, extern_block.get_abi (),
580+
std::move (extern_items), std::move (vis),
581+
extern_block.get_inner_attrs (),
582+
extern_block.get_outer_attrs (),
583+
extern_block.get_locus ());
584+
585+
translated = hir_extern_block;
586+
}
587+
556588
private:
557589
ASTLoweringItem () : translated (nullptr) {}
558590

gcc/rust/hir/tree/rust-hir-full-test.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3399,8 +3399,9 @@ ExternalFunctionItem::as_string () const
33993399
}
34003400
}
34013401

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

34053406
// where clause
34063407
str += "\n Where clause: ";

0 commit comments

Comments
 (0)