summaryrefslogtreecommitdiff
path: root/src/trans/codegen_c.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/trans/codegen_c.cpp')
-rw-r--r--src/trans/codegen_c.cpp287
1 files changed, 149 insertions, 138 deletions
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index 09b63f44..bd447191 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -945,7 +945,7 @@ namespace {
{
auto inner_ptr = ::HIR::TypeRef::new_pointer( ::HIR::BorrowType::Unique, inner_type.clone() );
m_of << indent; emit_ctype(inner_ptr, FMT_CB(ss, ss << "i"; )); m_of << " = "; emit_lvalue(slot); m_of << "._0._0._0;\n";
- emit_destructor_call( ::MIR::LValue::make_Local(~0u), inner_type, true, indent_level );
+ emit_destructor_call( ::MIR::LValue::new_Local(::MIR::LValue::Storage::MAX_ARG), inner_type, true, indent_level );
}
// TODO: This is specific to the official liballoc's owned_box
::HIR::GenericPath box_free { m_crate.get_lang_item_path(sp, "box_free"), { inner_type.clone() } };
@@ -976,7 +976,7 @@ namespace {
m_mir_res = &mir_res;
m_of << "static void " << Trans_Mangle(drop_glue_path) << "(struct s_" << Trans_Mangle(p) << "* rv) {\n";
- emit_box_drop(1, *ity, ::MIR::LValue::make_Deref({ box$(::MIR::LValue::make_Return({})) }), /*run_destructor=*/true);
+ emit_box_drop(1, *ity, ::MIR::LValue::new_Deref(::MIR::LValue::new_Return()), /*run_destructor=*/true);
m_of << "}\n";
m_mir_res = nullptr;
@@ -1122,13 +1122,13 @@ namespace {
m_of << "static void " << Trans_Mangle(drop_glue_path) << "("; emit_ctype(ty); m_of << "* rv) {\n";
if( m_resolve.type_needs_drop_glue(sp, ty) )
{
- auto self = ::MIR::LValue::make_Deref({ box$(::MIR::LValue::make_Return({})) });
- auto fld_lv = ::MIR::LValue::make_Field({ box$(self), 0 });
+ auto self = ::MIR::LValue::new_Deref(::MIR::LValue::new_Return());
+ auto fld_lv = ::MIR::LValue::new_Field(mv$(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 ++;
+ fld_lv.inc_Field();
}
}
m_of << "}\n";
@@ -1329,13 +1329,12 @@ namespace {
m_of << "\t" << Trans_Mangle( ::HIR::Path(struct_ty.clone(), m_resolve.m_lang_Drop, "drop") ) << "(rv);\n";
}
- auto self = ::MIR::LValue::make_Deref({ box$(::MIR::LValue::make_Return({})) });
- auto fld_lv = ::MIR::LValue::make_Field({ box$(self), 0 });
+ auto self = ::MIR::LValue::new_Deref(::MIR::LValue::new_Return());
+ auto fld_lv = ::MIR::LValue::new_Field(mv$(self), 0);
for(size_t i = 0; i < repr->fields.size(); i++)
{
- fld_lv.as_Field().field_index = i;
-
emit_destructor_call(fld_lv, repr->fields[i].ty, /*unsized_valid=*/true, /*indent=*/1);
+ fld_lv.inc_Field();
}
}
m_of << "}\n";
@@ -1573,14 +1572,14 @@ namespace {
{
m_of << "\t" << Trans_Mangle(drop_impl_path) << "(rv);\n";
}
- auto self = ::MIR::LValue::make_Deref({ box$(::MIR::LValue::make_Return({})) });
+ auto self = ::MIR::LValue::new_Deref(::MIR::LValue::new_Return());
if( const auto* e = repr->variants.opt_NonZero() )
{
unsigned idx = 1 - e->zero_variant;
// TODO: Fat pointers?
m_of << "\tif( (*rv)"; emit_enum_path(repr, e->field); m_of << " != 0 ) {\n";
- emit_destructor_call( ::MIR::LValue::make_Downcast({ box$(self), idx }), repr->fields[idx].ty, false, 2 );
+ emit_destructor_call( ::MIR::LValue::new_Downcast(mv$(self), idx), repr->fields[idx].ty, false, 2 );
m_of << "\t}\n";
}
else if( repr->fields.size() <= 1 )
@@ -1590,15 +1589,15 @@ namespace {
}
else if( const auto* e = repr->variants.opt_Values() )
{
- auto var_lv =::MIR::LValue::make_Downcast({ box$(self), 0 });
+ auto var_lv =::MIR::LValue::new_Downcast(mv$(self), 0);
m_of << "\tswitch(rv->TAG) {\n";
for(unsigned int var_idx = 0; var_idx < e->values.size(); var_idx ++)
{
- var_lv.as_Downcast().variant_index = var_idx;
m_of << "\tcase " << e->values[var_idx] << ":\n";
emit_destructor_call(var_lv, repr->fields[var_idx].ty, /*unsized_valid=*/false, /*indent=*/2);
m_of << "\t\tbreak;\n";
+ var_lv.inc_Downcast();
}
m_of << "\t}\n";
}
@@ -2874,8 +2873,8 @@ namespace {
break;
}
- TU_MATCHA( (e.src), (ve),
- (Use,
+ TU_MATCH_HDRA( (e.src), {)
+ TU_ARMA(Use, ve) {
::HIR::TypeRef tmp;
const auto& ty = mir_res.get_lvalue_type(tmp, ve);
if( ty == ::HIR::TypeRef::new_diverge() ) {
@@ -2892,13 +2891,13 @@ namespace {
emit_lvalue(e.dst);
m_of << " = ";
emit_lvalue(ve);
- ),
- (Constant,
+ }
+ TU_ARMA(Constant, ve) {
emit_lvalue(e.dst);
m_of << " = ";
emit_constant(ve, &e.dst);
- ),
- (SizedArray,
+ }
+ TU_ARMA(SizedArray, ve) {
if( ve.count == 0 ) {
}
else if( ve.count == 1 ) {
@@ -2917,34 +2916,35 @@ namespace {
m_of << "for(unsigned int i = 0; i < " << ve.count << "; i ++)\n";
m_of << indent << "\t"; emit_lvalue(e.dst); m_of << ".DATA[i] = "; emit_param(ve.val);
}
- ),
- (Borrow,
+ }
+ TU_ARMA(Borrow, ve) {
::HIR::TypeRef tmp;
const auto& ty = mir_res.get_lvalue_type(tmp, ve.val);
bool special = false;
// If the inner value was a deref, just copy the pointer verbatim
- TU_IFLET(::MIR::LValue, ve.val, Deref, le,
+ if( ve.val.is_Deref() )
+ {
emit_lvalue(e.dst);
m_of << " = ";
- emit_lvalue(*le.val);
+ emit_lvalue( ::MIR::LValue::CRef(ve.val).inner_ref() );
special = true;
- )
+ }
// Magic for taking a &-ptr to unsized field of a struct.
// - Needs to get metadata from bottom-level pointer.
- else TU_IFLET(::MIR::LValue, ve.val, Field, le,
+ else if( ve.val.is_Field() ) {
if( metadata_type(ty) != MetadataType::None ) {
- const ::MIR::LValue* base_val = &*le.val;
- while(base_val->is_Field())
- base_val = &*base_val->as_Field().val;
- MIR_ASSERT(mir_res, base_val->is_Deref(), "DST access must be via a deref");
- const ::MIR::LValue& base_ptr = *base_val->as_Deref().val;
+ auto base_val = ::MIR::LValue::CRef(ve.val).inner_ref();
+ while(base_val.is_Field())
+ base_val.try_unwrap();
+ MIR_ASSERT(mir_res, base_val.is_Deref(), "DST access must be via a deref");
+ const auto base_ptr = base_val.inner_ref();
// Construct the new DST
emit_lvalue(e.dst); m_of << ".META = "; emit_lvalue(base_ptr); m_of << ".META;\n" << indent;
emit_lvalue(e.dst); m_of << ".PTR = &"; emit_lvalue(ve.val);
special = true;
}
- )
+ }
else {
}
@@ -2953,50 +2953,55 @@ namespace {
if( !special && m_options.disallow_empty_structs && ve.val.is_Field() && this->type_is_bad_zst(ty) )
{
// Work backwards to the first non-ZST field
- const auto* val_fp = &ve.val.as_Field();
- while( val_fp->val->is_Field() )
+ auto val_fp = ::MIR::LValue::CRef(ve.val);
+ assert(val_fp.is_Field());
+ while( val_fp.inner_ref().is_Field() )
{
::HIR::TypeRef tmp;
- const auto& ty = mir_res.get_lvalue_type(tmp, *val_fp->val);
+ const auto& ty = mir_res.get_lvalue_type(tmp, val_fp.inner_ref());
if( !this->type_is_bad_zst(ty) )
break;
+ val_fp.try_unwrap();
}
+ assert(val_fp.is_Field());
// Here, we have `val_fp` be a LValue::Field that refers to a ZST, but the inner of the field points to a non-ZST or a local
emit_lvalue(e.dst);
m_of << " = ";
// If the index is zero, then the best option is to borrow the source
- if( val_fp->val->is_Downcast() )
+ auto field_inner = val_fp.inner_ref();
+ if( field_inner.is_Downcast() )
{
- m_of << "(void*)& "; emit_lvalue(*val_fp->val->as_Downcast().val);
+ m_of << "(void*)& "; emit_lvalue(field_inner.inner_ref());
}
- else if( val_fp->field_index == 0 )
+ else if( val_fp.as_Field() == 0 )
{
- m_of << "(void*)& "; emit_lvalue(*val_fp->val);
+ m_of << "(void*)& "; emit_lvalue(field_inner);
}
else
{
::HIR::TypeRef tmp;
- auto tmp_lv = ::MIR::LValue::make_Field({ box$(val_fp->val->clone()), val_fp->field_index - 1 });
+ auto tmp_lv = ::MIR::LValue::new_Field( field_inner.clone(), val_fp.as_Field() - 1 );
bool use_parent = false;
for(;;)
{
const auto& ty = mir_res.get_lvalue_type(tmp, tmp_lv);
if( !this->type_is_bad_zst(ty) )
break;
- if( tmp_lv.as_Field().field_index == 0 )
+ auto idx = tmp_lv.as_Field();
+ if( idx == 0 )
{
use_parent = true;
break;
}
- tmp_lv.as_Field().field_index -= 1;
+ tmp_lv.m_wrappers.back() = ::MIR::LValue::Wrapper::new_Field(idx - 1);
}
// Reached index zero, with still ZST
if( use_parent )
{
- m_of << "(void*)& "; emit_lvalue(*val_fp->val);
+ m_of << "(void*)& "; emit_lvalue(field_inner);
}
// Use the address after the previous item
else
@@ -3013,11 +3018,11 @@ namespace {
m_of << " = ";
m_of << "& "; emit_lvalue(ve.val);
}
- ),
- (Cast,
+ }
+ TU_ARMA(Cast, ve) {
emit_rvalue_cast(mir_res, e.dst, ve);
- ),
- (BinOp,
+ }
+ TU_ARMA(BinOp, ve) {
emit_lvalue(e.dst);
m_of << " = ";
::HIR::TypeRef tmp, tmp_r;
@@ -3168,8 +3173,8 @@ namespace {
{
m_of << ".lo";
}
- ),
- (UniOp,
+ }
+ TU_ARMA(UniOp, ve) {
::HIR::TypeRef tmp;
const auto& ty = mir_res.get_lvalue_type(tmp, e.dst);
@@ -3204,24 +3209,24 @@ namespace {
break;
}
emit_lvalue(ve.val);
- ),
- (DstMeta,
+ }
+ TU_ARMA(DstMeta, ve) {
emit_lvalue(e.dst);
m_of << " = ";
emit_lvalue(ve.val);
m_of << ".META";
- ),
- (DstPtr,
+ }
+ TU_ARMA(DstPtr, ve) {
emit_lvalue(e.dst);
m_of << " = ";
emit_lvalue(ve.val);
m_of << ".PTR";
- ),
- (MakeDst,
+ }
+ TU_ARMA(MakeDst, ve) {
emit_lvalue(e.dst); m_of << ".PTR = "; emit_param(ve.ptr_val); m_of << ";\n" << indent;
emit_lvalue(e.dst); m_of << ".META = "; emit_param(ve.meta_val);
- ),
- (Tuple,
+ }
+ TU_ARMA(Tuple, ve) {
bool has_emitted = false;
for(unsigned int j = 0; j < ve.vals.size(); j ++)
{
@@ -3245,15 +3250,15 @@ namespace {
m_of << "._" << j << " = ";
emit_param(ve.vals[j]);
}
- ),
- (Array,
+ }
+ TU_ARMA(Array, ve) {
for(unsigned int j = 0; j < ve.vals.size(); j ++) {
if( j != 0 ) m_of << ";\n" << indent;
emit_lvalue(e.dst); m_of << ".DATA[" << j << "] = ";
emit_param(ve.vals[j]);
}
- ),
- (Variant,
+ }
+ TU_ARMA(Variant, ve) {
const auto& tyi = m_crate.get_typeitem_by_path(sp, ve.path.m_path);
if( tyi.is_Union() )
{
@@ -3310,8 +3315,8 @@ namespace {
{
BUG(mir_res.sp, "Unexpected type in Variant");
}
- ),
- (Struct,
+ }
+ TU_ARMA(Struct, ve) {
if( ve.vals.empty() )
{
if( m_options.disallow_empty_structs )
@@ -3349,8 +3354,8 @@ namespace {
emit_param(ve.vals[j]);
}
}
- )
- )
+ }
+ }
m_of << ";";
m_of << "\t// " << e.dst << " = " << e.src;
m_of << "\n";
@@ -4432,7 +4437,7 @@ namespace {
// Nothing needs to be done, this just stops the destructor from running.
}
else if( name == "drop_in_place" ) {
- emit_destructor_call( ::MIR::LValue::make_Deref({ box$(e.args.at(0).as_LValue().clone()) }), params.m_types.at(0), true, 1 /* TODO: get from caller */ );
+ emit_destructor_call( ::MIR::LValue::new_Deref(e.args.at(0).as_LValue().clone()), params.m_types.at(0), true, /*indent_level=*/1 /* TODO: get from caller */ );
}
else if( name == "needs_drop" ) {
// Returns `true` if the actual type given as `T` requires drop glue;
@@ -5186,7 +5191,7 @@ namespace {
if( te.type == ::HIR::BorrowType::Owned )
{
// Call drop glue on inner.
- emit_destructor_call( ::MIR::LValue::make_Deref({ box$(slot.clone()) }), *te.inner, true, indent_level );
+ emit_destructor_call( ::MIR::LValue::new_Deref(slot.clone()), *te.inner, true, indent_level );
}
),
(Path,
@@ -5201,10 +5206,7 @@ namespace {
if( this->type_is_bad_zst(ty) && (slot.is_Field() || slot.is_Downcast()) )
{
m_of << indent << Trans_Mangle(p) << "((void*)&";
- if( slot.is_Field() )
- emit_lvalue(*slot.as_Field().val);
- else
- emit_lvalue(*slot.as_Downcast().val);
+ emit_lvalue(::MIR::LValue::CRef(slot).inner_ref());
m_of << ");\n";
}
else
@@ -5219,7 +5221,7 @@ namespace {
m_of << indent << Trans_Mangle(p) << "( " << make_fcn << "(";
if( slot.is_Deref() )
{
- emit_lvalue(*slot.as_Deref().val);
+ emit_lvalue( ::MIR::LValue::CRef(slot).inner_ref() );
m_of << ".PTR";
}
else
@@ -5227,10 +5229,10 @@ namespace {
m_of << "&"; emit_lvalue(slot);
}
m_of << ", ";
- const auto* lvp = &slot;
- while(const auto* le = lvp->opt_Field()) lvp = &*le->val;
- MIR_ASSERT(*m_mir_res, lvp->is_Deref(), "Access to unized type without a deref - " << *lvp << " (part of " << slot << ")");
- emit_lvalue(*lvp->as_Deref().val); m_of << ".META";
+ auto lvr = ::MIR::LValue::CRef(slot);
+ while(lvr.is_Field()) lvr.try_unwrap();
+ MIR_ASSERT(*m_mir_res, lvr.is_Deref(), "Access to unized type without a deref - " << lvr << " (part of " << slot << ")");
+ emit_lvalue(lvr.inner_ref()); m_of << ".META";
m_of << ") );\n";
break;
}
@@ -5240,7 +5242,7 @@ namespace {
if( te.size_val > 0 )
{
m_of << indent << "for(unsigned i = 0; i < " << te.size_val << "; i++) {\n";
- emit_destructor_call(::MIR::LValue::make_Index({ box$(slot.clone()), box$(::MIR::LValue::make_Local(~0u)) }), *te.inner, false, indent_level+1);
+ emit_destructor_call(::MIR::LValue::new_Index(slot.clone(), ::MIR::LValue::Storage::MAX_ARG), *te.inner, false, indent_level+1);
m_of << "\n" << indent << "}";
}
),
@@ -5248,24 +5250,24 @@ namespace {
// Emit destructors for all entries
if( te.size() > 0 )
{
- ::MIR::LValue lv = ::MIR::LValue::make_Field({ box$(slot.clone()), 0 });
+ ::MIR::LValue lv = ::MIR::LValue::new_Field(slot.clone(), 0);
for(unsigned int i = 0; i < te.size(); i ++)
{
- lv.as_Field().field_index = i;
emit_destructor_call(lv, te[i], unsized_valid && (i == te.size()-1), indent_level);
+ lv.inc_Field();
}
}
),
(TraitObject,
MIR_ASSERT(*m_mir_res, unsized_valid, "Dropping TraitObject without a pointer");
// Call destructor in vtable
- const auto* lvp = &slot;
- while(const auto* le = lvp->opt_Field()) lvp = &*le->val;
- MIR_ASSERT(*m_mir_res, lvp->is_Deref(), "Access to unized type without a deref - " << *lvp << " (part of " << slot << ")");
- m_of << indent << "((VTABLE_HDR*)"; emit_lvalue(*lvp->as_Deref().val); m_of << ".META)->drop(";
- if( const auto* ve = slot.opt_Deref() )
+ auto lvr = ::MIR::LValue::CRef(slot);
+ while(lvr.is_Field()) lvr.try_unwrap();
+ MIR_ASSERT(*m_mir_res, lvr.is_Deref(), "Access to unized type without a deref - " << lvr << " (part of " << slot << ")");
+ m_of << indent << "((VTABLE_HDR*)"; emit_lvalue(lvr.inner_ref()); m_of << ".META)->drop(";
+ if( slot.is_Deref() )
{
- emit_lvalue(*ve->val); m_of << ".PTR";
+ emit_lvalue(::MIR::LValue::CRef(slot).inner_ref()); m_of << ".PTR";
}
else
{
@@ -5275,12 +5277,12 @@ namespace {
),
(Slice,
MIR_ASSERT(*m_mir_res, unsized_valid, "Dropping Slice without a pointer");
- const auto* lvp = &slot;
- while(const auto* le = lvp->opt_Field()) lvp = &*le->val;
- MIR_ASSERT(*m_mir_res, lvp->is_Deref(), "Access to unized type without a deref - " << *lvp << " (part of " << slot << ")");
+ auto lvr = ::MIR::LValue::CRef(slot);
+ while(lvr.is_Field()) lvr.try_unwrap();
+ MIR_ASSERT(*m_mir_res, lvr.is_Deref(), "Access to unized type without a deref - " << lvr << " (part of " << slot << ")");
// Call destructor on all entries
- m_of << indent << "for(unsigned i = 0; i < "; emit_lvalue(*lvp->as_Deref().val); m_of << ".META; i++) {\n";
- emit_destructor_call(::MIR::LValue::make_Index({ box$(slot.clone()), box$(::MIR::LValue::make_Local(~0u)) }), *te.inner, false, indent_level+1);
+ m_of << indent << "for(unsigned i = 0; i < "; emit_lvalue(lvr.inner_ref()); m_of << ".META; i++) {\n";
+ emit_destructor_call(::MIR::LValue::new_Index(slot.clone(), ::MIR::LValue::Storage::MAX_ARG), *te.inner, false, indent_level+1);
m_of << "\n" << indent << "}";
)
)
@@ -5525,116 +5527,125 @@ namespace {
)
}
- void emit_lvalue(const ::MIR::LValue& val) {
- TU_MATCHA( (val), (e),
- (Return,
+ void emit_lvalue(const ::MIR::LValue::CRef& val)
+ {
+ TU_MATCH_HDRA( (val), {)
+ TU_ARMA(Return, _e) {
m_of << "rv";
- ),
- (Argument,
- m_of << "arg" << e.idx;
- ),
- (Local,
- if( e == ~0u )
+ }
+ TU_ARMA(Argument, e) {
+ m_of << "arg" << e;
+ }
+ TU_ARMA(Local, e) {
+ if( e == ::MIR::LValue::Storage::MAX_ARG )
m_of << "i";
else
m_of << "var" << e;
- ),
- (Static,
- m_of << Trans_Mangle(*e);
- ),
- (Field,
+ }
+ TU_ARMA(Static, e) {
+ m_of << Trans_Mangle(e);
+ }
+ TU_ARMA(Field, field_index) {
::HIR::TypeRef tmp;
- const auto& ty = m_mir_res->get_lvalue_type(tmp, *e.val);
- if( ty.m_data.is_Slice() ) {
- if( e.val->is_Deref() )
+ auto inner = val.inner_ref();
+ const auto& ty = m_mir_res->get_lvalue_type(tmp, inner);
+ if( ty.m_data.is_Slice() )
+ {
+ if( inner.is_Deref() )
{
m_of << "(("; emit_ctype(*ty.m_data.as_Slice().inner); m_of << "*)";
- emit_lvalue(*e.val->as_Deref().val);
+ emit_lvalue(inner.inner_ref());
m_of << ".PTR)";
}
else
{
- emit_lvalue(*e.val);
+ emit_lvalue(inner);
}
- m_of << "[" << e.field_index << "]";
+ m_of << "[" << field_index << "]";
}
else if( ty.m_data.is_Array() ) {
- emit_lvalue(*e.val);
- m_of << ".DATA[" << e.field_index << "]";
+ emit_lvalue(inner);
+ m_of << ".DATA[" << field_index << "]";
}
- else if( e.val->is_Deref() ) {
+ else if( inner.is_Deref() ) {
auto dst_type = metadata_type(ty);
if( dst_type != MetadataType::None )
{
- m_of << "(("; emit_ctype(ty); m_of << "*)"; emit_lvalue(*e.val->as_Deref().val); m_of << ".PTR)->_" << e.field_index;
+ m_of << "(("; emit_ctype(ty); m_of << "*)"; emit_lvalue(inner.inner_ref()); m_of << ".PTR)->_" << field_index;
}
else
{
- emit_lvalue(*e.val->as_Deref().val);
- m_of << "->_" << e.field_index;
+ emit_lvalue(inner.inner_ref());
+ m_of << "->_" << field_index;
}
}
else {
- emit_lvalue(*e.val);
- m_of << "._" << e.field_index;
+ emit_lvalue(inner);
+ m_of << "._" << field_index;
}
- ),
- (Deref,
- // TODO: If the type is unsized, then this pointer is a fat pointer, so we need to cast the data pointer.
+ }
+ TU_ARMA(Deref, _e) {
+ auto inner = val.inner_ref();
::HIR::TypeRef tmp;
const auto& ty = m_mir_res->get_lvalue_type(tmp, val);
auto dst_type = metadata_type(ty);
+ // If the type is unsized, then this pointer is a fat pointer, so we need to cast the data pointer.
if( dst_type != MetadataType::None )
{
m_of << "(*("; emit_ctype(ty); m_of << "*)";
- emit_lvalue(*e.val);
+ emit_lvalue(inner);
m_of << ".PTR)";
}
else
{
m_of << "(*";
- emit_lvalue(*e.val);
+ emit_lvalue(inner);
m_of << ")";
}
- ),
- (Index,
+ }
+ TU_ARMA(Index, index_local) {
+ auto inner = val.inner_ref();
::HIR::TypeRef tmp;
- const auto& ty = m_mir_res->get_lvalue_type(tmp, *e.val);
+ const auto& ty = m_mir_res->get_lvalue_type(tmp, inner);
m_of << "(";
if( ty.m_data.is_Slice() ) {
- if( e.val->is_Deref() )
+ if( inner.is_Deref() )
{
m_of << "("; emit_ctype(*ty.m_data.as_Slice().inner); m_of << "*)";
- emit_lvalue(*e.val->as_Deref().val);
+ emit_lvalue(inner.inner_ref());
m_of << ".PTR";
}
else {
- emit_lvalue(*e.val);
+ emit_lvalue(inner);
}
}
else if( ty.m_data.is_Array() ) {
- emit_lvalue(*e.val);
+ emit_lvalue(inner);
m_of << ".DATA";
}
else {
- emit_lvalue(*e.val);
+ emit_lvalue(inner);
}
m_of << ")[";
- emit_lvalue(*e.idx);
+ emit_lvalue(::MIR::LValue::new_Local(index_local));
m_of << "]";
- ),
- (Downcast,
+ }
+ TU_ARMA(Downcast, variant_index) {
+ auto inner = val.inner_ref();
::HIR::TypeRef tmp;
- const auto& ty = m_mir_res->get_lvalue_type(tmp, *e.val);
- emit_lvalue(*e.val);
+ const auto& ty = m_mir_res->get_lvalue_type(tmp, inner);
+ emit_lvalue(inner);
MIR_ASSERT(*m_mir_res, ty.m_data.is_Path(), "Downcast on non-Path type - " << ty);
if( ty.m_data.as_Path().binding.is_Enum() )
{
m_of << ".DATA";
}
- m_of << ".var_" << e.variant_index;
- )
- )
+ m_of << ".var_" << variant_index;
+ }
+ }
+ }
+ void emit_lvalue(const ::MIR::LValue& val) {
+ emit_lvalue( ::MIR::LValue::CRef(val) );
}
void emit_constant(const ::MIR::Constant& ve, const ::MIR::LValue* dst_ptr=nullptr)
{