summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-12-09 14:28:08 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-12-09 14:28:08 +0800
commit30aa97ca3d479719b78cbaaa3a1327c66d98de0c (patch)
treeb27d80a099de68f0990d821e3bb2efb9800de855 /src
parent79318f8896fad735225938fc130f3a450565a162 (diff)
downloadmrust-30aa97ca3d479719b78cbaaa3a1327c66d98de0c.tar.gz
HIR+Trans - Handling of various enum reprs
Diffstat (limited to 'src')
-rw-r--r--src/hir/from_ast.cpp16
-rw-r--r--src/hir/hir.hpp2
-rw-r--r--src/trans/codegen_c.cpp58
-rw-r--r--src/trans/target.cpp1
4 files changed, 48 insertions, 29 deletions
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index f413e21e..fcd7dbf2 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -917,8 +917,24 @@ namespace {
if( repr_str == "C" ) {
repr = ::HIR::Enum::Repr::C;
}
+ else if( repr_str == "u8") {
+ repr = ::HIR::Enum::Repr::U8;
+ }
+ else if( repr_str == "u16") {
+ repr = ::HIR::Enum::Repr::U16;
+ }
+ else if( repr_str == "u32") {
+ repr = ::HIR::Enum::Repr::U32;
+ }
+ else if( repr_str == "u64") {
+ repr = ::HIR::Enum::Repr::U32;
+ }
+ else if( repr_str == "usize") {
+ repr = ::HIR::Enum::Repr::Usize;
+ }
else {
// TODO: Other repr types
+ ERROR(Span(), E0000, "Unknown enum repr '" << repr_str << "'");
}
}
data = ::HIR::Enum::Class::make_Value({ repr, mv$(variants) });
diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp
index a7c8c6e8..be83b7c3 100644
--- a/src/hir/hir.hpp
+++ b/src/hir/hir.hpp
@@ -222,7 +222,7 @@ public:
{
Rust,
C,
- U8, U16, U32,
+ Usize, U8, U16, U32, U64,
};
struct ValueVariant {
::std::string name;
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index a88333b3..59bb4921 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -1190,6 +1190,9 @@ namespace {
case ::HIR::Enum::Repr::C:
m_of << "\tunsigned int TAG;\n";
break;
+ case ::HIR::Enum::Repr::Usize:
+ m_of << "\tuintptr_t TAG;\n";
+ break;
case ::HIR::Enum::Repr::U8:
m_of << "\tuint8_t TAG;\n";
break;
@@ -1199,6 +1202,9 @@ namespace {
case ::HIR::Enum::Repr::U32:
m_of << "\tuint32_t TAG;\n";
break;
+ case ::HIR::Enum::Repr::U64:
+ m_of << "\tuint32_t TAG;\n";
+ break;
}
m_of << "};\n";
}
@@ -1975,15 +1981,18 @@ namespace {
)
}
- if( false )
+ const bool EMIT_STRUCTURED = false; // Saves time.
+ const bool USE_STRUCTURED = false; // Still not correct.
+ if( EMIT_STRUCTURED )
{
- m_of << "#if 0\n";
+ m_of << "#if " << USE_STRUCTURED << "\n";
auto nodes = MIR_To_Structured(*code);
for(const auto& node : nodes)
{
emit_fcn_node(mir_res, node, 1);
}
- m_of << "#endif\n";
+
+ m_of << "#else\n";
}
for(unsigned int i = 0; i < code->blocks.size(); i ++)
@@ -2000,7 +2009,6 @@ namespace {
// If the previous block is a goto/function call to this
// block, AND this block only has a single reference, omit the
// label.
- #if 1
if( bb_use_counts.at(i) == 0 )
{
if( i == 0 )
@@ -2028,9 +2036,6 @@ namespace {
{
m_of << "bb" << i << ":\n";
}
- #else
- m_of << "bb" << i << ":\n";
- #endif
for(const auto& stmt : code->blocks[i].statements)
{
@@ -2090,6 +2095,11 @@ namespace {
)
m_of << "\t// ^ " << code->blocks[i].terminator << "\n";
}
+
+ if( EMIT_STRUCTURED )
+ {
+ m_of << "#endif\n";
+ }
m_of << "}\n";
m_of.flush();
m_mir_res = nullptr;
@@ -2120,12 +2130,13 @@ namespace {
(Incomplete, ),
(Return,
assert(i == e.nodes.size()-1 && "Return");
- m_of << indent << "return;\n";
+ m_of << indent << "return rv;\n";
),
(Goto,
// Ignore (handled by caller)
),
(Diverge,
+ m_of << indent << "_Unwind_Resume();\n";
),
(Panic,
),
@@ -2183,8 +2194,6 @@ namespace {
});
),
(SwitchValue,
- // TODO: Change the logic in emit_term_switchvalue to not call multiple times.
- MIR_TODO(mir_res, "SwitchValue");
this->emit_term_switchvalue(mir_res, *e.val, *e.vals, indent_level, [&](auto idx) {
const auto& arm = (idx == SIZE_MAX ? e.def_arm : e.arms.at(idx));
if( arm.node ) {
@@ -2868,26 +2877,19 @@ namespace {
::HIR::TypeRef tmp;
const auto& ty = mir_res.get_lvalue_type(tmp, val);
if( const auto* ve = values.opt_String() ) {
- // TODO: Call a helper that searches a list of strings and returns an index
- // > This helper can do a binary search, or a linear
- //assert(ve->size() == e.targets.size());
- m_of << indent << "{ int cmp;\n";
- m_of << indent;
+ m_of << indent << "{ static SLICE_PTR switch_strings[] = {";
+ for(const auto& v : *ve)
+ {
+ m_of << " {"; this->print_escaped_string(v); m_of << "," << v.size() << "},";
+ }
+ m_of << " {0,0} };\n";
+ m_of << indent << "switch( mrustc_string_search_linear("; emit_lvalue(val); m_of << ", " << ve->size() << ", switch_strings) ) {\n";
for(size_t i = 0; i < ve->size(); i++)
{
- const auto& v = (*ve)[i];
- m_of << "if( (cmp = slice_cmp("; emit_lvalue(val); m_of << ", make_sliceptr("; this->print_escaped_string(v); m_of << "," << v.size() << "))) < 0)\n";
- m_of << indent << "\t"; cb(SIZE_MAX); m_of << "\n";
- m_of << indent << "else if( cmp == 0 )\n";
- m_of << indent << "\t"; cb(i); m_of << "\n";
- m_of << indent << "else ";
- }
- m_of << "{\n";
- // TODO: Insert a deterinistic label and use that instead of calling `cb(SIZE_MAX)` multiple times
- m_of << indent << "\t"; cb(SIZE_MAX); m_of << "\n";
- m_of << indent << "}\n";
-
- m_of << indent << "}\n";
+ m_of << indent << "case " << i << ": "; cb(i); m_of << " break;\n";
+ }
+ m_of << indent << "default: "; cb(SIZE_MAX); m_of << "\n";
+ m_of << indent << "} }\n";
}
else if( const auto* ve = values.opt_Unsigned() ) {
m_of << indent << "switch("; emit_lvalue(val);
diff --git a/src/trans/target.cpp b/src/trans/target.cpp
index c8413f2a..f13b20a3 100644
--- a/src/trans/target.cpp
+++ b/src/trans/target.cpp
@@ -96,6 +96,7 @@ void Target_SetCfg(const ::std::string& target_name)
if( g_target.m_os_name == "linux" )
{
Cfg_SetFlag("linux");
+ Cfg_SetValue("target_vendor", "gnu");
}
Cfg_SetValue("target_env", g_target.m_env_name);