Skip to content

Commit f76ddb4

Browse files
bors[bot]philberty
andauthored
Merge #598
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]>
2 parents 9526e6d + 7f8adcc commit f76ddb4

19 files changed

+513
-46
lines changed

gcc/rust/backend/rust-compile-context.h

+8-3
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,14 @@ class TyTyResolveCompile : public TyTy::TyVisitor
371371
parameters.push_back (compiled_param);
372372
}
373373

374-
translated = ctx->get_backend ()->function_type (
375-
receiver, parameters, results, NULL,
376-
ctx->get_mappings ()->lookup_location (type.get_ref ()));
374+
if (!type.is_varadic ())
375+
translated = ctx->get_backend ()->function_type (
376+
receiver, parameters, results, NULL,
377+
ctx->get_mappings ()->lookup_location (type.get_ref ()));
378+
else
379+
translated = ctx->get_backend ()->function_type_varadic (
380+
receiver, parameters, results, NULL,
381+
ctx->get_mappings ()->lookup_location (type.get_ref ()));
377382
}
378383

379384
void visit (TyTy::FnPtr &type) override
+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
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_COMPILE_EXTERN_ITEM
20+
#define RUST_COMPILE_EXTERN_ITEM
21+
22+
#include "rust-compile-base.h"
23+
#include "rust-compile-tyty.h"
24+
#include "rust-compile-implitem.h"
25+
#include "rust-compile-var-decl.h"
26+
#include "rust-compile-stmt.h"
27+
#include "rust-compile-expr.h"
28+
#include "rust-compile-fnparam.h"
29+
30+
namespace Rust {
31+
namespace Compile {
32+
33+
class CompileExternItem : public HIRCompileBase
34+
{
35+
using Rust::Compile::HIRCompileBase::visit;
36+
37+
public:
38+
static void compile (HIR::ExternalItem *item, Context *ctx,
39+
bool compile_fns = true,
40+
TyTy::BaseType *concrete = nullptr)
41+
{
42+
CompileExternItem compiler (ctx, compile_fns, concrete);
43+
item->accept_vis (compiler);
44+
}
45+
46+
void visit (HIR::ExternalStaticItem &item) override
47+
{
48+
TyTy::BaseType *resolved_type = nullptr;
49+
bool ok = ctx->get_tyctx ()->lookup_type (item.get_mappings ().get_hirid (),
50+
&resolved_type);
51+
rust_assert (ok);
52+
53+
std::string name = item.get_item_name ();
54+
// FIXME this is assuming C ABI
55+
std::string asm_name = name;
56+
57+
Btype *type = TyTyResolveCompile::compile (ctx, resolved_type);
58+
bool is_external = true;
59+
bool is_hidden = false;
60+
bool in_unique_section = false;
61+
62+
Bvariable *static_global
63+
= ctx->get_backend ()->global_variable (name, asm_name, type, is_external,
64+
is_hidden, in_unique_section,
65+
item.get_locus ());
66+
ctx->insert_var_decl (item.get_mappings ().get_hirid (), static_global);
67+
ctx->push_var (static_global);
68+
}
69+
70+
void visit (HIR::ExternalFunctionItem &function) override
71+
{
72+
if (!compile_fns)
73+
return;
74+
75+
TyTy::BaseType *fntype_tyty;
76+
if (!ctx->get_tyctx ()->lookup_type (function.get_mappings ().get_hirid (),
77+
&fntype_tyty))
78+
{
79+
rust_fatal_error (function.get_locus (),
80+
"failed to lookup function type");
81+
return;
82+
}
83+
84+
rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
85+
TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
86+
if (fntype->has_subsititions_defined ())
87+
{
88+
// we cant do anything for this only when it is used and a concrete type
89+
// is given
90+
if (concrete == nullptr)
91+
return;
92+
else
93+
{
94+
rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
95+
fntype = static_cast<TyTy::FnType *> (concrete);
96+
}
97+
}
98+
99+
// items can be forward compiled which means we may not need to invoke this
100+
// code. We might also have already compiled this generic function as well.
101+
Bfunction *lookup = nullptr;
102+
if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup, fntype))
103+
{
104+
// has this been added to the list then it must be finished
105+
if (ctx->function_completed (lookup))
106+
{
107+
Bfunction *dummy = nullptr;
108+
if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
109+
ctx->insert_function_decl (fntype->get_ty_ref (), lookup, fntype);
110+
111+
return;
112+
}
113+
}
114+
115+
if (fntype->has_subsititions_defined ())
116+
{
117+
// override the Hir Lookups for the substituions in this context
118+
fntype->override_context ();
119+
}
120+
121+
::Btype *compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
122+
123+
const unsigned int flags
124+
= Backend::function_is_declaration | Backend::function_is_visible;
125+
126+
std::string ir_symbol_name = function.get_item_name ();
127+
// FIXME this assumes C ABI
128+
std::string asm_name = function.get_item_name ();
129+
130+
Bfunction *fndecl
131+
= ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
132+
asm_name, flags, function.get_locus ());
133+
ctx->insert_function_decl (fntype->get_ty_ref (), fndecl, fntype);
134+
}
135+
136+
private:
137+
CompileExternItem (Context *ctx, bool compile_fns, TyTy::BaseType *concrete)
138+
: HIRCompileBase (ctx), compile_fns (compile_fns), concrete (concrete)
139+
{}
140+
141+
bool compile_fns;
142+
TyTy::BaseType *concrete;
143+
};
144+
145+
} // namespace Compile
146+
} // namespace Rust
147+
148+
#endif // RUST_COMPILE_EXTERN_ITEM

gcc/rust/backend/rust-compile-item.h

+9
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "rust-compile-stmt.h"
2727
#include "rust-compile-expr.h"
2828
#include "rust-compile-fnparam.h"
29+
#include "rust-compile-extern.h"
2930

3031
namespace Rust {
3132
namespace Compile {
@@ -274,6 +275,14 @@ class CompileItem : public HIRCompileBase
274275
compile_fns);
275276
}
276277

278+
void visit (HIR::ExternBlock &extern_block) override
279+
{
280+
for (auto &item : extern_block.get_extern_items ())
281+
{
282+
CompileExternItem::compile (item.get (), ctx, compile_fns, concrete);
283+
}
284+
}
285+
277286
private:
278287
CompileItem (Context *ctx, bool compile_fns, TyTy::BaseType *concrete)
279288
: HIRCompileBase (ctx), compile_fns (compile_fns), concrete (concrete)

gcc/rust/backend/rust-compile-tyty.h

+9-3
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,15 @@ class TyTyCompile : public TyTy::TyVisitor
9595
parameters.push_back (compiled_param);
9696
}
9797

98-
translated
99-
= backend->function_type (receiver, parameters, results, NULL,
100-
mappings->lookup_location (type.get_ref ()));
98+
if (!type.is_varadic ())
99+
translated
100+
= backend->function_type (receiver, parameters, results, NULL,
101+
mappings->lookup_location (type.get_ref ()));
102+
else
103+
translated
104+
= backend->function_type_varadic (receiver, parameters, results, NULL,
105+
mappings->lookup_location (
106+
type.get_ref ()));
101107
}
102108

103109
void visit (TyTy::BoolType &) override

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

+10-4
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ class ASTLoweringExternItem : public ASTLoweringBase
4747
Analysis::NodeMapping mapping (crate_num, item.get_node_id (),
4848
mappings->get_next_hir_id (crate_num),
4949
mappings->get_next_localdef_id (crate_num));
50-
mappings->insert_location (crate_num, mapping.get_hirid (),
51-
item.get_locus ());
5250

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

6058
translated = static_item;
59+
60+
mappings->insert_hir_extern_item (crate_num, mapping.get_hirid (),
61+
translated);
62+
mappings->insert_location (crate_num, mapping.get_hirid (),
63+
item.get_locus ());
6164
}
6265

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

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

109110
translated = function_item;
111+
112+
mappings->insert_hir_extern_item (crate_num, mapping.get_hirid (),
113+
translated);
114+
mappings->insert_location (crate_num, mapping.get_hirid (),
115+
function.get_locus ());
110116
}
111117

112118
private:

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

+6-4
Original file line numberDiff line numberDiff line change
@@ -571,10 +571,6 @@ class ASTLoweringItem : public ASTLoweringBase
571571
mappings->get_next_hir_id (crate_num),
572572
mappings->get_next_localdef_id (crate_num));
573573

574-
mappings->insert_defid_mapping (mapping.get_defid (), translated);
575-
mappings->insert_location (crate_num, mapping.get_hirid (),
576-
extern_block.get_locus ());
577-
578574
HIR::ExternBlock *hir_extern_block
579575
= new HIR::ExternBlock (mapping, extern_block.get_abi (),
580576
std::move (extern_items), std::move (vis),
@@ -583,6 +579,12 @@ class ASTLoweringItem : public ASTLoweringBase
583579
extern_block.get_locus ());
584580

585581
translated = hir_extern_block;
582+
583+
mappings->insert_defid_mapping (mapping.get_defid (), translated);
584+
mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (),
585+
translated);
586+
mappings->insert_location (crate_num, mapping.get_hirid (),
587+
extern_block.get_locus ());
586588
}
587589

588590
private:

gcc/rust/hir/tree/rust-hir-item.h

+29-3
Original file line numberDiff line numberDiff line change
@@ -2713,6 +2713,8 @@ class ExternalItem
27132713

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

2716+
Identifier get_item_name () const { return item_name; }
2717+
27162718
protected:
27172719
ExternalItem (Analysis::NodeMapping mappings, Identifier item_name,
27182720
Visibility vis, AST::AttrVec outer_attrs, Location locus)
@@ -2746,9 +2748,6 @@ class ExternalItem
27462748

27472749
// Clone function implementation as pure virtual method
27482750
virtual ExternalItem *clone_external_item_impl () const = 0;
2749-
2750-
// possibly make this public if required
2751-
std::string get_item_name () const { return item_name; }
27522751
};
27532752

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

27912790
void accept_vis (HIRVisitor &vis) override;
27922791

2792+
std::unique_ptr<Type> &get_item_type () { return item_type; }
2793+
27932794
protected:
27942795
/* Use covariance to implement clone function as returning this object
27952796
* rather than base */
@@ -2840,6 +2841,12 @@ struct NamedFunctionParam
28402841
NamedFunctionParam &operator= (NamedFunctionParam &&other) = default;
28412842

28422843
std::string as_string () const;
2844+
2845+
Identifier get_param_name () const { return name; }
2846+
2847+
std::unique_ptr<Type> &get_type () { return param_type; }
2848+
2849+
Analysis::NodeMapping get_mappings () const { return mappings; }
28432850
};
28442851

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

29212928
void accept_vis (HIRVisitor &vis) override;
29222929

2930+
std::vector<std::unique_ptr<GenericParam> > &get_generic_params ()
2931+
{
2932+
return generic_params;
2933+
}
2934+
2935+
std::unique_ptr<Type> &get_return_type () { return return_type; }
2936+
2937+
std::vector<NamedFunctionParam> &get_function_params ()
2938+
{
2939+
return function_params;
2940+
}
2941+
2942+
bool is_variadic () const { return has_variadics; }
2943+
29232944
protected:
29242945
/* Use covariance to implement clone function as returning this object
29252946
* rather than base */
@@ -2999,6 +3020,11 @@ class ExternBlock : public VisItem
29993020

30003021
void accept_vis (HIRVisitor &vis) override;
30013022

3023+
std::vector<std::unique_ptr<ExternalItem> > &get_extern_items ()
3024+
{
3025+
return extern_items;
3026+
}
3027+
30023028
protected:
30033029
/* Use covariance to implement clone function as returning this object
30043030
* rather than base */

gcc/rust/resolve/rust-ast-resolve-item.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ class ResolveExternItem : public ResolverBase
619619

620620
private:
621621
ResolveExternItem () : ResolverBase (UNKNOWN_NODEID) {}
622-
}; // namespace Resolver
622+
};
623623

624624
} // namespace Resolver
625625
} // namespace Rust

gcc/rust/resolve/rust-ast-resolve.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,9 @@ ResolveItem::resolve_impl_item (AST::InherentImplItem *item,
637637

638638
void
639639
ResolveItem::resolve_extern_item (AST::ExternalItem *item)
640-
{}
640+
{
641+
ResolveExternItem::go (item);
642+
}
641643

642644
} // namespace Resolver
643645
} // namespace Rust

gcc/rust/rust-backend.h

+7
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,13 @@ class Backend
163163
Btype *result_struct, Location location)
164164
= 0;
165165

166+
virtual Btype *
167+
function_type_varadic (const Btyped_identifier &receiver,
168+
const std::vector<Btyped_identifier> &parameters,
169+
const std::vector<Btyped_identifier> &results,
170+
Btype *result_struct, Location location)
171+
= 0;
172+
166173
virtual Btype *function_ptr_type (Btype *result,
167174
const std::vector<Btype *> &praameters,
168175
Location location)

0 commit comments

Comments
 (0)