Skip to content

Commit 9d8b19b

Browse files
committed
Hello World Works - Adds support for compilation of extern "C" functions.
``` 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
1 parent 9b8ffd2 commit 9d8b19b

File tree

2 files changed

+159
-0
lines changed

2 files changed

+159
-0
lines changed
+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
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+
55+
// FIXME
56+
// this is assuming C ABI
57+
std::string asm_name = "_" + name;
58+
59+
Btype *type = TyTyResolveCompile::compile (ctx, resolved_type);
60+
bool is_external = true;
61+
bool is_hidden = false;
62+
bool in_unique_section = false;
63+
64+
Bvariable *static_global
65+
= ctx->get_backend ()->global_variable (name, asm_name, type, is_external,
66+
is_hidden, in_unique_section,
67+
item.get_locus ());
68+
ctx->insert_var_decl (item.get_mappings ().get_hirid (), static_global);
69+
ctx->push_var (static_global);
70+
}
71+
72+
void visit (HIR::ExternalFunctionItem &function) override
73+
{
74+
if (!compile_fns)
75+
return;
76+
77+
TyTy::BaseType *fntype_tyty;
78+
if (!ctx->get_tyctx ()->lookup_type (function.get_mappings ().get_hirid (),
79+
&fntype_tyty))
80+
{
81+
rust_fatal_error (function.get_locus (),
82+
"failed to lookup function type");
83+
return;
84+
}
85+
86+
rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
87+
TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
88+
if (fntype->has_subsititions_defined ())
89+
{
90+
// we cant do anything for this only when it is used and a concrete type
91+
// is given
92+
if (concrete == nullptr)
93+
return;
94+
else
95+
{
96+
rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
97+
fntype = static_cast<TyTy::FnType *> (concrete);
98+
}
99+
}
100+
101+
// items can be forward compiled which means we may not need to invoke this
102+
// code. We might also have already compiled this generic function as well.
103+
Bfunction *lookup = nullptr;
104+
if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup, fntype))
105+
{
106+
// has this been added to the list then it must be finished
107+
if (ctx->function_completed (lookup))
108+
{
109+
Bfunction *dummy = nullptr;
110+
if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
111+
ctx->insert_function_decl (fntype->get_ty_ref (), lookup, fntype);
112+
113+
return;
114+
}
115+
}
116+
117+
if (fntype->has_subsititions_defined ())
118+
{
119+
// override the Hir Lookups for the substituions in this context
120+
fntype->override_context ();
121+
}
122+
123+
::Btype *compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
124+
125+
const unsigned int flags
126+
= Backend::function_is_declaration | Backend::function_is_visible;
127+
128+
std::string ir_symbol_name = function.get_item_name ();
129+
// FIXME this assumes C ABI
130+
std::string asm_name = function.get_item_name ();
131+
132+
Bfunction *fndecl
133+
= ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
134+
asm_name, flags, function.get_locus ());
135+
ctx->insert_function_decl (fntype->get_ty_ref (), fndecl, fntype);
136+
}
137+
138+
private:
139+
CompileExternItem (Context *ctx, bool compile_fns, TyTy::BaseType *concrete)
140+
: HIRCompileBase (ctx), compile_fns (compile_fns), concrete (concrete)
141+
{}
142+
143+
bool compile_fns;
144+
TyTy::BaseType *concrete;
145+
};
146+
147+
} // namespace Compile
148+
} // namespace Rust
149+
150+
#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)

0 commit comments

Comments
 (0)