summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--src/expand/proc_macro.cpp4
-rw-r--r--src/hir/from_ast.cpp8
-rw-r--r--src/main.cpp4
-rw-r--r--src/trans/codegen_c.cpp85
-rw-r--r--src/trans/target.cpp14
-rw-r--r--tools/minicargo/build.cpp5
-rw-r--r--tools/minicargo/manifest.cpp4
-rw-r--r--tools/testrunner/Makefile2
9 files changed, 110 insertions, 18 deletions
diff --git a/README.md b/README.md
index c19f2926..439bae83 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ Intro
===
This project is an attempt at creating a simple rust compiler in C++, with the ultimate goal of being a separate re-implementation.
-`mrustc` works by comping assumed-valid rust code (i.e. without borrow checking) into a high-level assembly (currently using C, but LLVM/cretonne or even direct machine code could work) and getting an external code generator to turn that into optimised machine code. This works because the borrow checker doesn't have any impact on the generated code, just in checking that the code would be valid.
+`mrustc` works by compiling assumed-valid rust code (i.e. without borrow checking) into a high-level assembly (currently using C, but LLVM/cretonne or even direct machine code could work) and getting an external code generator to turn that into optimised machine code. This works because the borrow checker doesn't have any impact on the generated code, just in checking that the code would be valid.
Progress
--------
diff --git a/src/expand/proc_macro.cpp b/src/expand/proc_macro.cpp
index 5c06a8ce..d34a91a5 100644
--- a/src/expand/proc_macro.cpp
+++ b/src/expand/proc_macro.cpp
@@ -24,7 +24,7 @@
# include <sys/wait.h>
#endif
-#ifdef __OpenBSD__
+#if defined(__OpenBSD__) || defined(__NetBSD__)
extern char **environ;
#endif
@@ -797,7 +797,7 @@ ProcMacroInv::ProcMacroInv(const Span& sp, const char* executable, const ::HIR::
int stdout_pipes[2];
if( pipe(stdout_pipes) != 0)
{
- BUG(sp, "Unable to create stdin pipe pair for proc macro, " << strerror(errno));
+ BUG(sp, "Unable to create stdout pipe pair for proc macro, " << strerror(errno));
}
this->child_stdout = stdout_pipes[0]; // Read end
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index 760339fe..99408020 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -1206,8 +1206,12 @@ namespace {
bool force_emit = false;
if( const auto* a = attrs.get("inline") )
{
- (void)a;
- force_emit = true;
+ if( a->has_sub_items() && ::std::any_of(a->items().begin(), a->items().end(), [](const auto& v){ return v.name() == "never"; }) ) {
+ // Inline(never)
+ }
+ else {
+ force_emit = true;
+ }
}
::HIR::Linkage linkage;
diff --git a/src/main.cpp b/src/main.cpp
index c63ce0d6..369c80de 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -52,6 +52,10 @@
# else
# define DEFAULT_TARGET_NAME "i586-windows-gnu"
# endif
+#elif defined(__NetBSD__)
+# if defined(__amd64__)
+# define DEFAULT_TARGET_NAME "x86_64-unknown-netbsd"
+# endif
#elif defined(__OpenBSD__)
# if defined(__amd64__)
# define DEFAULT_TARGET_NAME "x86_64-unknown-openbsd"
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index 87d96abb..0171f19f 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -213,6 +213,7 @@ namespace {
{
m_options.emulated_i128 = true;
}
+ m_options.disallow_empty_structs = true;
break;
case CodegenMode::Msvc:
m_compiler = Compiler::Msvc;
@@ -706,10 +707,20 @@ namespace {
::std::cerr << "INVOKE CC: " << cmd_ss.str() << ::std::endl;
::std::ofstream(opt.build_command_file) << cmd_ss.str() << ::std::endl;
}
- else if( system(cmd_ss.str().c_str()) != 0 )
+ else
{
- ::std::cerr << "C Compiler failed to execute" << ::std::endl;
- abort();
+ int ec = system(cmd_ss.str().c_str());
+ if( ec == -1 )
+ {
+ ::std::cerr << "C Compiler failed to execute (system returned -1)" << ::std::endl;
+ perror("system");
+ exit(1);
+ }
+ else if( ec != 0 )
+ {
+ ::std::cerr << "C Compiler failed to execute - error code " << ec << ::std::endl;
+ exit(1);
+ }
}
}
@@ -844,8 +855,16 @@ namespace {
for(unsigned int i = 0; i < te.size(); i++)
{
m_of << "\t";
- emit_ctype(te[i], FMT_CB(ss, ss << "_" << i;));
- m_of << ";\n";
+ size_t s, a;
+ Target_GetSizeAndAlignOf(sp, m_resolve, te[i], s, a);
+ if( s == 0 && m_options.disallow_empty_structs ) {
+ m_of << "// ZST: " << te[i] << "\n";
+ continue ;
+ }
+ else {
+ emit_ctype(te[i], FMT_CB(ss, ss << "_" << i;));
+ m_of << ";\n";
+ }
}
m_of << "} "; emit_ctype(ty); m_of << ";\n";
}
@@ -862,6 +881,7 @@ namespace {
auto fld_lv = ::MIR::LValue::make_Field({ box$(self), 0 });
for(const auto& ity : te)
{
+ // TODO: What if it's a ZST?
emit_destructor_call(fld_lv, ity, /*unsized_valid=*/false, 1);
fld_lv.as_Field().field_index ++;
}
@@ -1267,7 +1287,11 @@ namespace {
void emit_constructor_enum(const Span& sp, const ::HIR::GenericPath& path, const ::HIR::Enum& item, size_t var_idx) override
{
+ ::MIR::Function empty_fcn;
+ ::MIR::TypeResolve top_mir_res { sp, m_resolve, FMT_CB(ss, ss << "enum cons " << path;), ::HIR::TypeRef(), {}, empty_fcn };
+ m_mir_res = &top_mir_res;
TRACE_FUNCTION_F(path << " var_idx=" << var_idx);
+
::HIR::TypeRef tmp;
auto monomorph = [&](const auto& x)->const auto& {
if( monomorphise_type_needed(x) ) {
@@ -1329,17 +1353,25 @@ namespace {
else
{
m_of << " .DATA = { .var_" << var_idx << " = {";
- for(unsigned int i = 0; i < e.size(); i ++)
+ if( this->type_is_bad_zst(repr->fields[var_idx].ty) )
{
- if(i != 0)
- m_of << ",";
- m_of << "\n\t\t_" << i;
+ m_of << "\n\t\t0";
+ }
+ else
+ {
+ for(unsigned int i = 0; i < e.size(); i ++)
+ {
+ if(i != 0)
+ m_of << ",";
+ m_of << "\n\t\t_" << i;
+ }
}
m_of << "\n\t\t}";
}
m_of << " }};\n";
m_of << "\treturn rv;\n";
m_of << "}\n";
+ m_mir_res = nullptr;
}
void emit_constructor_struct(const Span& sp, const ::HIR::GenericPath& p, const ::HIR::Struct& item) override
{
@@ -2468,6 +2500,15 @@ namespace {
const auto& e = stmt.as_Assign();
DEBUG("- " << e.dst << " = " << e.src);
m_of << indent;
+
+ ::HIR::TypeRef tmp;
+ const auto& ty = mir_res.get_lvalue_type(tmp, e.dst);
+ if( e.dst.is_Deref() && this->type_is_bad_zst(ty) )
+ {
+ m_of << "/* ZST deref */";
+ break;
+ }
+
TU_MATCHA( (e.src), (ve),
(Use,
::HIR::TypeRef tmp;
@@ -3337,6 +3378,11 @@ namespace {
const auto& name = e.fcn.as_Intrinsic().name;
const auto& params = e.fcn.as_Intrinsic().params;
emit_intrinsic_call(name, params, e);
+ if( has_zst )
+ {
+ indent.n --;
+ m_of << indent << "}\n";
+ }
return ;
)
)
@@ -3884,7 +3930,11 @@ namespace {
const auto& ty_dst = params.m_types.at(0);
const auto& ty_src = params.m_types.at(1);
auto is_ptr = [](const ::HIR::TypeRef& ty){ return ty.m_data.is_Borrow() || ty.m_data.is_Pointer(); };
- if( e.args.at(0).is_Constant() )
+ if( this->type_is_bad_zst(ty_dst) )
+ {
+ m_of << "/* zst */";
+ }
+ else if( e.args.at(0).is_Constant() )
{
m_of << "{ "; emit_ctype(ty_src, FMT_CB(s, s << "v";)); m_of << " = "; emit_param(e.args.at(0)); m_of << ";";
m_of << "memcpy( &"; emit_lvalue(e.ret_val); m_of << ", &v, sizeof("; emit_ctype(ty_dst); m_of << ")); ";
@@ -3922,6 +3972,10 @@ namespace {
}
}
else if( name == "copy_nonoverlapping" || name == "copy" ) {
+ if( this->type_is_bad_zst(params.m_types.at(0)) ) {
+ m_of << "/* zst */";
+ return ;
+ }
if( name == "copy" ) {
m_of << "memmove";
}
@@ -3935,6 +3989,10 @@ namespace {
m_of << ")";
}
else if( name == "write_bytes" ) {
+ if( this->type_is_bad_zst(params.m_types.at(0)) ) {
+ m_of << "/* zst */";
+ return ;
+ }
// 0: Destination, 1: Value, 2: Count
m_of << "if( "; emit_param(e.args.at(2)); m_of << " > 0) memset( "; emit_param(e.args.at(0));
m_of << ", "; emit_param(e.args.at(1));
@@ -3968,7 +4026,10 @@ namespace {
m_of << "memset( &"; emit_lvalue(e.ret_val); m_of << ", 0, sizeof("; emit_ctype(params.m_types.at(0)); m_of << "))";
}
else if( name == "move_val_init" ) {
- m_of << "*"; emit_param(e.args.at(0)); m_of << " = "; emit_param(e.args.at(1));
+ if( !this->type_is_bad_zst(params.m_types.at(0)) )
+ {
+ m_of << "*"; emit_param(e.args.at(0)); m_of << " = "; emit_param(e.args.at(1));
+ }
}
else if( name == "abort" ) {
m_of << "abort()";
@@ -5269,7 +5330,9 @@ namespace {
else {
m_of << "TUP_" << te.size();
for(const auto& t : te)
+ {
m_of << "_" << Trans_Mangle(t);
+ }
}
m_of << " " << inner;
),
diff --git a/src/trans/target.cpp b/src/trans/target.cpp
index 54c3e7df..1d683af9 100644
--- a/src/trans/target.cpp
+++ b/src/trans/target.cpp
@@ -252,6 +252,13 @@ namespace
ARCH_X86_64
};
}
+ else if(target_name == "x86_64-unknown-netbsd")
+ {
+ return TargetSpec {
+ "unix", "netbsd", "gnu", CodegenMode::Gnu11, "x86_64-unknown-netbsd",
+ ARCH_X86_64
+ };
+ }
else if(target_name == "i686-unknown-openbsd")
{
return TargetSpec {
@@ -305,6 +312,13 @@ void Target_SetCfg(const ::std::string& target_name)
}
Cfg_SetValue("target_env", g_target.m_env_name);
+ if( g_target.m_os_name == "netbsd" )
+ {
+ Cfg_SetFlag("netbsd");
+ Cfg_SetValue("target_vendor", "unknown");
+ }
+ Cfg_SetValue("target_env", g_target.m_env_name);
+
if( g_target.m_os_name == "openbsd" )
{
Cfg_SetFlag("openbsd");
diff --git a/tools/minicargo/build.cpp b/tools/minicargo/build.cpp
index bde2b09d..c7c07256 100644
--- a/tools/minicargo/build.cpp
+++ b/tools/minicargo/build.cpp
@@ -51,6 +51,9 @@ extern int _putenv_s(const char*, const char*);
# define HOST_TARGET "x86_64-windows-gnu"
# else
# endif
+#elif defined(__NetBSD__)
+# define EXESUF ""
+# define HOST_TARGET "x86_64-unknown-netbsd"
#else
# define EXESUF ""
# define HOST_TARGET "x86_64-unknown-linux-gnu"
@@ -641,7 +644,7 @@ bool Builder::build_target(const PackageManifest& manifest, const PackageTarget&
}
if( true /*this->enable_debug*/ ) {
args.push_back("-g");
- //args.push_back("--cfg"); args.push_back("debug_assertions");
+ args.push_back("--cfg"); args.push_back("debug_assertions");
}
if( true /*this->enable_optimise*/ ) {
args.push_back("-O");
diff --git a/tools/minicargo/manifest.cpp b/tools/minicargo/manifest.cpp
index 3cb59113..6e2bf451 100644
--- a/tools/minicargo/manifest.cpp
+++ b/tools/minicargo/manifest.cpp
@@ -14,6 +14,10 @@
# define TARGET_NAME "i586-windows-msvc"
# define CFG_UNIX false
# define CFG_WINDOWS true
+#elif defined(__NetBSD__)
+# define TARGET_NAME "x86_64-unknown-netbsd"
+# define CFG_UNIX true
+# define CFG_WINDOWS false
#else
# define TARGET_NAME "x86_64-unknown-linux-gnu"
# define CFG_UNIX true
diff --git a/tools/testrunner/Makefile b/tools/testrunner/Makefile
index 7107eaf2..a81cd6b2 100644
--- a/tools/testrunner/Makefile
+++ b/tools/testrunner/Makefile
@@ -15,7 +15,7 @@ OBJS := $(OBJS:%=$(OBJDIR)%)
all: $(BIN)
clean:
- rm $(BIN) $(OBJS)
+ rm $(BIN) $(OBJS) $(OBJS:%.o=%.o.dep)
$(BIN): $(OBJS)
@mkdir -p $(dir $@)