diff options
author | John Hodge <tpg@ucc.asn.au> | 2017-12-09 14:28:08 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2017-12-09 14:28:08 +0800 |
commit | 30aa97ca3d479719b78cbaaa3a1327c66d98de0c (patch) | |
tree | b27d80a099de68f0990d821e3bb2efb9800de855 /src | |
parent | 79318f8896fad735225938fc130f3a450565a162 (diff) | |
download | mrust-30aa97ca3d479719b78cbaaa3a1327c66d98de0c.tar.gz |
HIR+Trans - Handling of various enum reprs
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/from_ast.cpp | 16 | ||||
-rw-r--r-- | src/hir/hir.hpp | 2 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 58 | ||||
-rw-r--r-- | src/trans/target.cpp | 1 |
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); |