summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-02-22 20:45:43 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-02-22 20:45:43 +0800
commit0b672c4325967ade9a8f9bd8a06071cca09c4276 (patch)
treea5cc6d90a59a4aa4b06e1a8a77d874670653f94a
parent1e8376b6bc4289832112a70323f8c1f0f0722392 (diff)
downloadmrust-0b672c4325967ade9a8f9bd8a06071cca09c4276.tar.gz
MIR - Add types to integer constants
-rw-r--r--src/hir/deserialise.cpp19
-rw-r--r--src/hir/serialise.cpp11
-rw-r--r--src/hir_conv/constant_evaluation.cpp8
-rw-r--r--src/hir_expand/const_eval_full.cpp8
-rw-r--r--src/mir/cleanup.cpp18
-rw-r--r--src/mir/dump.cpp8
-rw-r--r--src/mir/from_hir.cpp29
-rw-r--r--src/mir/from_hir_match.cpp100
-rw-r--r--src/mir/mir.cpp18
-rw-r--r--src/mir/mir.hpp19
-rw-r--r--src/mir/optimise.cpp2
-rw-r--r--src/trans/codegen_c.cpp34
12 files changed, 151 insertions, 123 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp
index c9c94be3..4a9b5720 100644
--- a/src/hir/deserialise.cpp
+++ b/src/hir/deserialise.cpp
@@ -430,10 +430,21 @@ namespace {
switch( m_in.read_tag() )
{
#define _(x, ...) case ::MIR::Constant::TAG_##x: DEBUG("- " #x); return ::MIR::Constant::make_##x( __VA_ARGS__ );
- _(Int, m_in.read_i64c())
- _(Uint, m_in.read_u64c())
- _(Float, m_in.read_double())
- _(Bool, m_in.read_bool())
+ _(Int, {
+ m_in.read_i64c(),
+ static_cast< ::HIR::CoreType>(m_in.read_tag())
+ })
+ _(Uint, {
+ m_in.read_u64c(),
+ static_cast< ::HIR::CoreType>(m_in.read_tag())
+ })
+ _(Float, {
+ m_in.read_double(),
+ static_cast< ::HIR::CoreType>(m_in.read_tag())
+ })
+ _(Bool, {
+ m_in.read_bool()
+ })
case ::MIR::Constant::TAG_Bytes: {
::std::vector<unsigned char> bytes;
bytes.resize( m_in.read_count() );
diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp
index 5a74e798..81319c2e 100644
--- a/src/hir/serialise.cpp
+++ b/src/hir/serialise.cpp
@@ -663,16 +663,19 @@ namespace {
m_out.write_tag(v.tag());
TU_MATCHA( (v), (e),
(Int,
- m_out.write_i64c(e);
+ m_out.write_i64c(e.v);
+ m_out.write_tag(static_cast<unsigned>(e.t));
),
(Uint,
- m_out.write_u64c(e);
+ m_out.write_u64c(e.v);
+ m_out.write_tag(static_cast<unsigned>(e.t));
),
(Float,
- m_out.write_double(e);
+ m_out.write_double(e.v);
+ m_out.write_tag(static_cast<unsigned>(e.t));
),
(Bool,
- m_out.write_bool(e);
+ m_out.write_bool(e.v);
),
(Bytes,
m_out.write_count(e.size());
diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp
index be27e0a4..a70840ed 100644
--- a/src/hir_conv/constant_evaluation.cpp
+++ b/src/hir_conv/constant_evaluation.cpp
@@ -1086,16 +1086,16 @@ namespace {
auto const_to_lit = [&](const ::MIR::Constant& c)->::HIR::Literal {
TU_MATCH(::MIR::Constant, (c), (e2),
(Int,
- return ::HIR::Literal(static_cast<uint64_t>(e2));
+ return ::HIR::Literal(static_cast<uint64_t>(e2.v));
),
(Uint,
- return ::HIR::Literal(e2);
+ return ::HIR::Literal(e2.v);
),
(Float,
- return ::HIR::Literal(e2);
+ return ::HIR::Literal(e2.v);
),
(Bool,
- return ::HIR::Literal(static_cast<uint64_t>(e2));
+ return ::HIR::Literal(static_cast<uint64_t>(e2.v));
),
(Bytes,
return ::HIR::Literal::make_String({e2.begin(), e2.end()});
diff --git a/src/hir_expand/const_eval_full.cpp b/src/hir_expand/const_eval_full.cpp
index a88d6075..a361ce59 100644
--- a/src/hir_expand/const_eval_full.cpp
+++ b/src/hir_expand/const_eval_full.cpp
@@ -388,16 +388,16 @@ namespace {
auto const_to_lit = [&](const ::MIR::Constant& c)->::HIR::Literal {
TU_MATCH(::MIR::Constant, (c), (e2),
(Int,
- return ::HIR::Literal(static_cast<uint64_t>(e2));
+ return ::HIR::Literal(static_cast<uint64_t>(e2.v));
),
(Uint,
- return ::HIR::Literal(e2);
+ return ::HIR::Literal(e2.v);
),
(Float,
- return ::HIR::Literal(e2);
+ return ::HIR::Literal(e2.v);
),
(Bool,
- return ::HIR::Literal(static_cast<uint64_t>(e2));
+ return ::HIR::Literal(static_cast<uint64_t>(e2.v));
),
(Bytes,
return ::HIR::Literal::make_String({e2.begin(), e2.end()});
diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp
index 8ab78ab2..a1da936e 100644
--- a/src/mir/cleanup.cpp
+++ b/src/mir/cleanup.cpp
@@ -341,19 +341,19 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR
case ::HIR::CoreType::U32:
case ::HIR::CoreType::U16:
case ::HIR::CoreType::U8:
- return ::MIR::Constant::make_Uint( lit.as_Integer() );
+ return ::MIR::Constant::make_Uint({ lit.as_Integer(), te });
case ::HIR::CoreType::Isize:
case ::HIR::CoreType::I128:
case ::HIR::CoreType::I64:
case ::HIR::CoreType::I32:
case ::HIR::CoreType::I16:
case ::HIR::CoreType::I8:
- return ::MIR::Constant::make_Int( lit.as_Integer() );
+ return ::MIR::Constant::make_Int({ static_cast<int64_t>(lit.as_Integer()), te });
case ::HIR::CoreType::F64:
case ::HIR::CoreType::F32:
- return ::MIR::Constant::make_Float( lit.as_Float() );
+ return ::MIR::Constant::make_Float({ lit.as_Float(), te });
case ::HIR::CoreType::Bool:
- return ::MIR::Constant::make_Bool( !!lit.as_Integer() );
+ return ::MIR::Constant::make_Bool({ !!lit.as_Integer() });
case ::HIR::CoreType::Str:
MIR_BUG(state, "Const of type `str` - " << path);
}
@@ -365,7 +365,7 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR
MIR_TODO(state, "BorrowOf into pointer - " << lit << " into " << ty);
}
else {
- auto lval = mutator.in_temporary( ::HIR::CoreType::Usize, ::MIR::RValue( ::MIR::Constant::make_Uint( lit.as_Integer() ) ) );
+ auto lval = mutator.in_temporary( ::HIR::CoreType::Usize, ::MIR::RValue( ::MIR::Constant::make_Uint({ lit.as_Integer(), ::HIR::CoreType::Usize }) ) );
return ::MIR::RValue::make_Cast({ mv$(lval), mv$(ty) });
}
),
@@ -384,7 +384,7 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR
auto ptr_type = ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Shared, (&ty == &tmp ? mv$(tmp) : ty.clone()) );
auto ptr_lval = mutator.in_temporary( mv$(ptr_type), ::MIR::Constant::make_ItemAddr(path.clone()) );
- auto size_lval = mutator.in_temporary( ::HIR::CoreType::Usize, ::MIR::Constant::make_Uint(size) );
+ auto size_lval = mutator.in_temporary( ::HIR::CoreType::Usize, ::MIR::Constant::make_Uint({ size, ::HIR::CoreType::Usize }) );
return ::MIR::RValue::make_MakeDst({ mv$(ptr_lval), mv$(size_lval) });
}
else if( const auto* tep = te.inner->m_data.opt_TraitObject() )
@@ -604,7 +604,7 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator&
{
const auto& in_array = src_ty.m_data.as_Array();
out_meta_ty = ::HIR::CoreType::Usize;
- out_meta_val = ::MIR::Constant( static_cast<uint64_t>(in_array.size_val) );
+ out_meta_val = ::MIR::Constant::make_Uint({ static_cast<uint64_t>(in_array.size_val), ::HIR::CoreType::Usize });
return true;
}
else if( src_ty.m_data.is_Generic() || (src_ty.m_data.is_Path() && src_ty.m_data.as_Path().binding.is_Opaque()) )
@@ -632,7 +632,7 @@ bool MIR_Cleanup_Unsize_GetMetadata(const ::MIR::TypeResolve& state, MirMutator&
// - Codegen assumes it's a pointer.
if( de.m_trait.m_path.m_path == ::HIR::SimplePath() )
{
- auto null_lval = mutator.in_temporary( ::HIR::CoreType::Usize, ::MIR::Constant::make_Uint(0u) );
+ auto null_lval = mutator.in_temporary( ::HIR::CoreType::Usize, ::MIR::Constant::make_Uint({ 0u, ::HIR::CoreType::Usize }) );
out_meta_ty = ty_unit_ptr.clone();
out_meta_val = ::MIR::RValue::make_Cast({ mv$(null_lval), mv$(ty_unit_ptr) });
}
@@ -987,7 +987,7 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path,
BUG(Span(), "Unexpected input type for DstMeta - " << ty);
}
if( const auto* te = ity_p->m_data.opt_Array() ) {
- se.src = ::MIR::Constant::make_Uint( te->size_val );
+ se.src = ::MIR::Constant::make_Uint({ te->size_val, ::HIR::CoreType::Usize });
}
),
(DstPtr,
diff --git a/src/mir/dump.cpp b/src/mir/dump.cpp
index 1342e086..f3dee478 100644
--- a/src/mir/dump.cpp
+++ b/src/mir/dump.cpp
@@ -196,16 +196,16 @@ namespace {
void fmt_val(::std::ostream& os, const ::MIR::Constant& e) {
TU_MATCHA( (e), (ce),
(Int,
- os << ce;
+ os << ce.v;
),
(Uint,
- os << "0x" << ::std::hex << ce << ::std::dec;
+ os << "0x" << ::std::hex << ce.v << ::std::dec;
),
(Float,
- os << ce;
+ os << ce.v;
),
(Bool,
- os << (ce ? "true" : "false");
+ os << (ce.v ? "true" : "false");
),
(Bytes,
os << "b\"" << ce << "\"";
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index 36d3adc4..0029432f 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -331,7 +331,7 @@ namespace {
if( e.extra_bind.is_valid() )
{
// 1. Obtain remaining length
- auto sub_val = m_builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue::make_Constant( e.leading.size() + e.trailing.size() ));
+ auto sub_val = m_builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::Constant::make_Uint({ e.leading.size() + e.trailing.size(), ::HIR::CoreType::Usize }));
::MIR::LValue len_val = m_builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue::make_BinOp({ len_lval.clone(), ::MIR::eBinOp::SUB, mv$(sub_val) }) );
// 2. Obtain pointer to element
@@ -934,7 +934,7 @@ namespace {
{
// If left is true, assign result true and return
m_builder.set_cur_block( bb_true );
- m_builder.push_stmt_assign(node.span(), res.clone(), ::MIR::RValue( ::MIR::Constant::make_Bool(true) ));
+ m_builder.push_stmt_assign(node.span(), res.clone(), ::MIR::RValue( ::MIR::Constant::make_Bool({true}) ));
m_builder.end_block( ::MIR::Terminator::make_Goto(bb_next) );
// If left is false, assign result to right
@@ -944,7 +944,7 @@ namespace {
{
// If left is false, assign result false and return
m_builder.set_cur_block( bb_false );
- m_builder.push_stmt_assign(node.span(), res.clone(), ::MIR::RValue( ::MIR::Constant::make_Bool(false) ));
+ m_builder.push_stmt_assign(node.span(), res.clone(), ::MIR::RValue( ::MIR::Constant::make_Bool({false}) ));
m_builder.end_block( ::MIR::Terminator::make_Goto(bb_next) );
// If left is true, assign result to right
@@ -1244,7 +1244,7 @@ namespace {
if( ty_in.m_data.is_Array() )
{
const auto& in_array = ty_in.m_data.as_Array();
- auto size_lval = m_builder.lvalue_or_temp( node.span(), ::HIR::TypeRef(::HIR::CoreType::Usize), ::MIR::Constant( static_cast<uint64_t>(in_array.size_val) ) );
+ auto size_lval = m_builder.lvalue_or_temp( node.span(), ::HIR::TypeRef(::HIR::CoreType::Usize), ::MIR::Constant::make_Uint({ static_cast<uint64_t>(in_array.size_val), ::HIR::CoreType::Usize } ) );
m_builder.set_result( node.span(), ::MIR::RValue::make_MakeDst({ mv$(ptr_lval), mv$(size_lval) }) );
}
else if( ty_in.m_data.is_Generic() || (ty_in.m_data.is_Path() && ty_in.m_data.as_Path().binding.is_Opaque()) )
@@ -1294,7 +1294,7 @@ namespace {
BUG(node.span(), "Indexing unsupported type " << ty_val);
),
(Array,
- limit_val = ::MIR::Constant( e.size_val );
+ limit_val = ::MIR::Constant::make_Uint({ e.size_val, ::HIR::CoreType::Usize });
),
(Slice,
limit_val = ::MIR::RValue::make_DstMeta({ m_builder.get_ptr_to_dst(node.m_value->span(), value).clone() });
@@ -1681,7 +1681,8 @@ namespace {
TU_MATCHA( (node.m_data), (e),
(Integer,
ASSERT_BUG(node.span(), node.m_res_type.m_data.is_Primitive(), "Non-primitive return type for Integer literal - " << node.m_res_type);
- switch(node.m_res_type.m_data.as_Primitive())
+ auto ity = node.m_res_type.m_data.as_Primitive();
+ switch(ity)
{
case ::HIR::CoreType::U8:
case ::HIR::CoreType::U16:
@@ -1689,7 +1690,10 @@ namespace {
case ::HIR::CoreType::U64:
case ::HIR::CoreType::U128:
case ::HIR::CoreType::Usize:
- m_builder.set_result(node.span(), ::MIR::RValue( ::MIR::Constant(e.m_value) ));
+ m_builder.set_result(node.span(), ::MIR::Constant::make_Uint({ e.m_value, ity }) );
+ break;
+ case ::HIR::CoreType::Char:
+ m_builder.set_result(node.span(), ::MIR::Constant::make_Uint({ static_cast<uint64_t>(e.m_value), ity }) );
break;
case ::HIR::CoreType::I8:
case ::HIR::CoreType::I16:
@@ -1697,20 +1701,19 @@ namespace {
case ::HIR::CoreType::I64:
case ::HIR::CoreType::I128:
case ::HIR::CoreType::Isize:
- m_builder.set_result(node.span(), ::MIR::RValue( ::MIR::Constant( static_cast<int64_t>(e.m_value) ) ));
- break;
- case ::HIR::CoreType::Char:
- m_builder.set_result(node.span(), ::MIR::RValue( ::MIR::Constant( static_cast<uint64_t>(e.m_value) ) ));
+ m_builder.set_result(node.span(), ::MIR::Constant::make_Int({ static_cast<int64_t>(e.m_value), ity }) );
break;
default:
BUG(node.span(), "Integer literal with unexpected type - " << node.m_res_type);
}
),
(Float,
- m_builder.set_result(node.span(), ::MIR::RValue::make_Constant( ::MIR::Constant(e.m_value) ));
+ ASSERT_BUG(node.span(), node.m_res_type.m_data.is_Primitive(), "Non-primitive return type for Float literal - " << node.m_res_type);
+ auto ity = node.m_res_type.m_data.as_Primitive();
+ m_builder.set_result(node.span(), ::MIR::RValue::make_Constant( ::MIR::Constant::make_Float({ e.m_value, ity }) ));
),
(Boolean,
- m_builder.set_result(node.span(), ::MIR::RValue::make_Constant( ::MIR::Constant(e) ));
+ m_builder.set_result(node.span(), ::MIR::RValue::make_Constant( ::MIR::Constant::make_Bool({e}) ));
),
(String,
m_builder.set_result(node.span(), ::MIR::RValue::make_Constant( ::MIR::Constant(e) ));
diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp
index a657ffd5..05ba510a 100644
--- a/src/mir/from_hir_match.cpp
+++ b/src/mir/from_hir_match.cpp
@@ -515,7 +515,7 @@ void PatternRulesetBuilder::append_from_lit(const Span& sp, const ::HIR::Literal
// Yes, this is valid.
ASSERT_BUG(sp, lit.is_Float(), "Matching floating point type with non-float literal - " << lit);
double val = lit.as_Float();
- this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) );
+ this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Float({ val, e }) ) );
} break;
case ::HIR::CoreType::U8:
case ::HIR::CoreType::U16:
@@ -525,7 +525,7 @@ void PatternRulesetBuilder::append_from_lit(const Span& sp, const ::HIR::Literal
case ::HIR::CoreType::Usize: {
ASSERT_BUG(sp, lit.is_Integer(), "Matching integer type with non-integer literal - " << lit);
uint64_t val = lit.as_Integer();
- this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) );
+ this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Uint({val, e}) ) );
} break;
case ::HIR::CoreType::I8:
case ::HIR::CoreType::I16:
@@ -535,7 +535,7 @@ void PatternRulesetBuilder::append_from_lit(const Span& sp, const ::HIR::Literal
case ::HIR::CoreType::Isize: {
ASSERT_BUG(sp, lit.is_Integer(), "Matching integer type with non-integer literal - " << lit);
int64_t val = static_cast<int64_t>( lit.as_Integer() );
- this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) );
+ this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Int({ val, e }) ) );
} break;
case ::HIR::CoreType::Bool:
ASSERT_BUG(sp, lit.is_Integer(), "Matching boolean with non-integer literal - " << lit);
@@ -545,7 +545,7 @@ void PatternRulesetBuilder::append_from_lit(const Span& sp, const ::HIR::Literal
// Char is just another name for 'u32'... but with a restricted range
ASSERT_BUG(sp, lit.is_Integer(), "Matching char with non-integer literal - " << lit);
uint64_t val = lit.as_Integer();
- this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) );
+ this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Uint({ val, e }) ) );
} break;
case ::HIR::CoreType::Str:
BUG(sp, "Hit match over `str` - must be `&str`");
@@ -807,7 +807,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa
case ::HIR::CoreType::F64: {
double start = H::get_pattern_value_float(sp, pat, pe.start);
double end = H::get_pattern_value_float(sp, pat, pe.end );
- this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant(start), ::MIR::Constant(end)} ) );
+ this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant::make_Float({ start, e }), ::MIR::Constant::make_Float({ end, e })} ) );
} break;
case ::HIR::CoreType::U8:
case ::HIR::CoreType::U16:
@@ -817,7 +817,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa
case ::HIR::CoreType::Usize: {
uint64_t start = H::get_pattern_value_int(sp, pat, pe.start);
uint64_t end = H::get_pattern_value_int(sp, pat, pe.end );
- this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant(start), ::MIR::Constant(end)} ) );
+ this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant::make_Uint({ start, e }), ::MIR::Constant::make_Uint({ end, e })} ) );
} break;
case ::HIR::CoreType::I8:
case ::HIR::CoreType::I16:
@@ -827,7 +827,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa
case ::HIR::CoreType::Isize: {
int64_t start = H::get_pattern_value_int(sp, pat, pe.start);
int64_t end = H::get_pattern_value_int(sp, pat, pe.end );
- this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant(start), ::MIR::Constant(end)} ) );
+ this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant::make_Int({ start, e }), ::MIR::Constant::make_Int({ end, e })} ) );
} break;
case ::HIR::CoreType::Bool:
BUG(sp, "Can't range match on Bool");
@@ -835,7 +835,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa
case ::HIR::CoreType::Char: {
uint64_t start = H::get_pattern_value_int(sp, pat, pe.start);
uint64_t end = H::get_pattern_value_int(sp, pat, pe.end );
- this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant(start), ::MIR::Constant(end)} ) );
+ this->push_rule( PatternRule::make_ValueRange( {::MIR::Constant::make_Uint({ start, e }), ::MIR::Constant::make_Uint({ end, e })} ) );
} break;
case ::HIR::CoreType::Str:
BUG(sp, "Hit match over `str` - must be `&str`");
@@ -849,7 +849,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa
case ::HIR::CoreType::F64: {
// Yes, this is valid.
double val = H::get_pattern_value_float(sp, pat, pe.val);
- this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) );
+ this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Float({ val, e }) ) );
} break;
case ::HIR::CoreType::U8:
case ::HIR::CoreType::U16:
@@ -858,7 +858,12 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa
case ::HIR::CoreType::U128:
case ::HIR::CoreType::Usize: {
uint64_t val = H::get_pattern_value_int(sp, pat, pe.val);
- this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) );
+ this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Uint({ val, e }) ) );
+ } break;
+ case ::HIR::CoreType::Char: {
+ // Char is just another name for 'u32'... but with a restricted range
+ uint64_t val = H::get_pattern_value_int(sp, pat, pe.val);
+ this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Uint({ val, e }) ) );
} break;
case ::HIR::CoreType::I8:
case ::HIR::CoreType::I16:
@@ -867,17 +872,12 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa
case ::HIR::CoreType::I128:
case ::HIR::CoreType::Isize: {
int64_t val = H::get_pattern_value_int(sp, pat, pe.val);
- this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) );
+ this->push_rule( PatternRule::make_Value( ::MIR::Constant::make_Int({ val, e }) ) );
} break;
case ::HIR::CoreType::Bool:
// TODO: Support values from `const` too
this->push_rule( PatternRule::make_Bool( pe.val.as_Integer().value != 0 ) );
break;
- case ::HIR::CoreType::Char: {
- // Char is just another name for 'u32'... but with a restricted range
- uint64_t val = H::get_pattern_value_int(sp, pat, pe.val);
- this->push_rule( PatternRule::make_Value( ::MIR::Constant(val) ) );
- } break;
case ::HIR::CoreType::Str:
BUG(sp, "Hit match over `str` - must be `&str`");
break;
@@ -1548,7 +1548,7 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span&
(Value,
auto succ_bb = builder.new_bb_unlinked();
- auto test_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant(re.as_Uint()));
+ auto test_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant::make_Uint({ re.as_Uint().v, te }));
auto cmp_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ val.clone(), ::MIR::eBinOp::EQ, mv$(test_lval) }));
builder.end_block( ::MIR::Terminator::make_If({ mv$(cmp_lval), succ_bb, fail_bb }) );
builder.set_cur_block(succ_bb);
@@ -1571,7 +1571,7 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span&
(Value,
auto succ_bb = builder.new_bb_unlinked();
- auto test_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant(re.as_Int()));
+ auto test_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant::make_Int({ re.as_Int().v, te }));
auto cmp_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ val.clone(), ::MIR::eBinOp::EQ, mv$(test_lval) }));
builder.end_block( ::MIR::Terminator::make_If({ mv$(cmp_lval), succ_bb, fail_bb }) );
builder.set_cur_block(succ_bb);
@@ -1589,8 +1589,8 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span&
(Value,
auto succ_bb = builder.new_bb_unlinked();
- auto test_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant(re.as_Uint()));
- auto cmp_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ val.clone(), ::MIR::eBinOp::EQ, mv$(test_lval) }));
+ auto test_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant::make_Uint({ re.as_Uint().v, te }));
+ auto cmp_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ ::MIR::Param(val.clone()), ::MIR::eBinOp::EQ, mv$(test_lval) }));
builder.end_block( ::MIR::Terminator::make_If({ mv$(cmp_lval), succ_bb, fail_bb }) );
builder.set_cur_block(succ_bb);
),
@@ -1599,15 +1599,15 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span&
auto test_bb_2 = builder.new_bb_unlinked();
// IF `val` < `first` : fail_bb
- auto test_lt_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant(re.first.as_Uint()));
- auto cmp_lt_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ val.clone(), ::MIR::eBinOp::LT, mv$(test_lt_lval) }));
+ auto test_lt_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant::make_Uint({ re.first.as_Uint().v, te }));
+ auto cmp_lt_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ ::MIR::Param(val.clone()), ::MIR::eBinOp::LT, mv$(test_lt_lval) }));
builder.end_block( ::MIR::Terminator::make_If({ mv$(cmp_lt_lval), fail_bb, test_bb_2 }) );
builder.set_cur_block(test_bb_2);
// IF `val` > `last` : fail_bb
- auto test_gt_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant(re.last.as_Uint()));
- auto cmp_gt_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ val.clone(), ::MIR::eBinOp::GT, mv$(test_gt_lval) }));
+ auto test_gt_lval = builder.lvalue_or_temp(sp, te, ::MIR::Constant::make_Uint({ re.last.as_Uint().v, te }));
+ auto cmp_gt_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ ::MIR::Param(val.clone()), ::MIR::eBinOp::GT, mv$(test_gt_lval) }));
builder.end_block( ::MIR::Terminator::make_If({ mv$(cmp_gt_lval), fail_bb, succ_bb }) );
builder.set_cur_block(succ_bb);
@@ -1768,7 +1768,7 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span&
const auto& re = rule.as_Slice();
// Compare length
- auto test_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue( ::MIR::Constant::make_Uint(re.len) ));
+ auto test_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue( ::MIR::Constant::make_Uint({ re.len, ::HIR::CoreType::Usize }) ));
auto len_val = builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue::make_DstMeta({ builder.get_ptr_to_dst(sp, val).clone() }));
auto cmp_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ mv$(len_val), ::MIR::eBinOp::EQ, mv$(test_lval) }));
@@ -1787,7 +1787,7 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span&
const auto& re = rule.as_SplitSlice();
// Compare length
- auto test_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue( ::MIR::Constant::make_Uint(re.min_len) ));
+ auto test_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue( ::MIR::Constant::make_Uint({ re.min_len, ::HIR::CoreType::Usize}) ));
auto len_val = builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::RValue::make_DstMeta({ builder.get_ptr_to_dst(sp, val).clone() }));
auto cmp_lval = builder.lvalue_or_temp(sp, ::HIR::CoreType::Bool, ::MIR::RValue::make_BinOp({ mv$(len_val), ::MIR::eBinOp::LT, mv$(test_lval) }));
@@ -2535,8 +2535,7 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule
(Int,
auto& be = GET_BRANCHES(m_branches, Signed);
- // TODO: De-duplicate this code between Uint and Float
- from_rule_value(sp, be, ve, "Signed", rule.field_path,
+ from_rule_value(sp, be, ve.v, "Signed", rule.field_path,
[&](auto& branch) {
if( rule_count > 1 ) {
assert( branch.as_Subtree() );
@@ -2552,7 +2551,7 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule
(Uint,
auto& be = GET_BRANCHES(m_branches, Unsigned);
- from_rule_value(sp, be, ve, "Unsigned", rule.field_path,
+ from_rule_value(sp, be, ve.v, "Unsigned", rule.field_path,
[&](auto& branch) {
if( rule_count > 1 ) {
assert( branch.as_Subtree() );
@@ -2568,7 +2567,7 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule
(Float,
auto& be = GET_BRANCHES(m_branches, Float);
- from_rule_value(sp, be, ve, "Float", rule.field_path,
+ from_rule_value(sp, be, ve.v, "Float", rule.field_path,
[&](auto& branch) {
if( rule_count > 1 ) {
assert( branch.as_Subtree() );
@@ -2581,7 +2580,7 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule
});
),
(Bool,
- throw "";
+ BUG(sp, "Hit Bool in PatternRule::Value - " << e);
),
(Bytes,
TODO(sp, "Value patterns - Bytes");
@@ -2606,20 +2605,20 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule
}
),
(Const,
- throw "";
+ BUG(sp, "Hit Const in PatternRule::Value - " << e);
),
(ItemAddr,
- throw "";
+ BUG(sp, "Hit ItemAddr in PatternRule::Value - " << e);
)
)
),
(ValueRange,
- ASSERT_BUG(sp, e.first.tag() == e.last.tag(), "");
+ ASSERT_BUG(sp, e.first.tag() == e.last.tag(), "Constant type mismatch in ValueRange - " << e.first << " and " << e.last);
TU_MATCHA( (e.first, e.last), (ve_start, ve_end),
(Int,
auto& be = GET_BRANCHES(m_branches, Signed);
- from_rule_valuerange(sp, be, ve_start, ve_end, "Signed", rule.field_path,
+ from_rule_valuerange(sp, be, ve_start.v, ve_end.v, "Signed", rule.field_path,
[&](auto& branch) {
if( rule_count > 1 )
{
@@ -2636,7 +2635,7 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule
(Uint,
// TODO: Share code between the three numeric groups
auto& be = GET_BRANCHES(m_branches, Unsigned);
- from_rule_valuerange(sp, be, ve_start, ve_end, "Unsigned", rule.field_path,
+ from_rule_valuerange(sp, be, ve_start.v, ve_end.v, "Unsigned", rule.field_path,
[&](auto& branch) {
if( rule_count > 1 )
{
@@ -2652,7 +2651,7 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule
),
(Float,
auto& be = GET_BRANCHES(m_branches, Float);
- from_rule_valuerange(sp, be, ve_start, ve_end, "Float", rule.field_path,
+ from_rule_valuerange(sp, be, ve_start.v, ve_end.v, "Float", rule.field_path,
[&](auto& branch) {
if( rule_count > 1 )
{
@@ -2667,7 +2666,7 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule
});
),
(Bool,
- throw "";
+ BUG(sp, "Hit Bool in PatternRule::ValueRange - " << e.first);
),
(Bytes,
TODO(sp, "ValueRange patterns - Bytes");
@@ -2676,10 +2675,10 @@ void DecisionTreeNode::populate_tree_from_rule(const Span& sp, const PatternRule
ERROR(sp, E0000, "Use of string in value range patter");
),
(Const,
- throw "";
+ BUG(sp, "Hit Const in PatternRule::ValueRange - " << e.first);
),
(ItemAddr,
- throw "";
+ BUG(sp, "Hit ItemAddr in PatternRule::ValueRange - " << e.first);
)
)
)
@@ -3285,6 +3284,7 @@ void DecisionTreeGen::generate_branches_Signed(
::std::function<void(const DecisionTreeNode&)> and_then
)
{
+ auto ity = ty.m_data.as_Primitive();
auto default_block = m_builder.new_bb_unlinked();
// TODO: Convert into an integer switch w/ offset instead of chained comparisons
@@ -3293,8 +3293,8 @@ void DecisionTreeGen::generate_branches_Signed(
{
auto next_block = (&branch == &branches.back() ? default_block : m_builder.new_bb_unlinked());
- auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.start));
- auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.end)));
+ auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Int({branch.first.start, ity}));
+ auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Int({ branch.first.end, ity })));
auto cmp_gt_block = m_builder.new_bb_unlinked();
auto val_cmp_lt = m_builder.lvalue_or_temp(sp, ::HIR::TypeRef(::HIR::CoreType::Bool), ::MIR::RValue::make_BinOp({
@@ -3332,6 +3332,7 @@ void DecisionTreeGen::generate_branches_Unsigned(
::std::function<void(const DecisionTreeNode&)> and_then
)
{
+ auto ity = ty.m_data.as_Primitive();
auto default_block = m_builder.new_bb_unlinked();
// TODO: Convert into an integer switch w/ offset instead of chained comparisons
@@ -3340,8 +3341,8 @@ void DecisionTreeGen::generate_branches_Unsigned(
{
auto next_block = (&branch == &branches.back() ? default_block : m_builder.new_bb_unlinked());
- auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.start));
- auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.end)));
+ auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Uint({ branch.first.start, ity }));
+ auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Uint({ branch.first.end, ity })));
auto cmp_gt_block = m_builder.new_bb_unlinked();
auto val_cmp_lt = m_builder.lvalue_or_temp(sp, ::HIR::TypeRef(::HIR::CoreType::Bool), ::MIR::RValue::make_BinOp({
@@ -3379,14 +3380,15 @@ void DecisionTreeGen::generate_branches_Float(
::std::function<void(const DecisionTreeNode&)> and_then
)
{
+ auto ity = ty.m_data.as_Primitive();
auto default_block = m_builder.new_bb_unlinked();
for( const auto& branch : branches )
{
auto next_block = (&branch == &branches.back() ? default_block : m_builder.new_bb_unlinked());
- auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.start));
- auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.end)));
+ auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Float({ branch.first.start, ity }));
+ auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Float({ branch.first.end, ity })));
auto cmp_gt_block = m_builder.new_bb_unlinked();
auto val_cmp_lt = m_builder.lvalue_or_temp(sp, ::HIR::TypeRef(::HIR::CoreType::Bool), ::MIR::RValue::make_BinOp({
@@ -3431,8 +3433,8 @@ void DecisionTreeGen::generate_branches_Char(
{
auto next_block = (&branch == &branches.back() ? default_block : m_builder.new_bb_unlinked());
- auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.start));
- auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant(branch.first.end)));
+ auto val_start = m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Uint({ branch.first.start, ::HIR::CoreType::Char }));
+ auto val_end = (branch.first.end == branch.first.start ? val_start.clone() : m_builder.lvalue_or_temp(sp, ty, ::MIR::Constant::make_Uint({ branch.first.end, ::HIR::CoreType::Char })));
auto cmp_gt_block = m_builder.new_bb_unlinked();
auto val_cmp_lt = m_builder.lvalue_or_temp( sp, ::HIR::TypeRef(::HIR::CoreType::Bool), ::MIR::RValue::make_BinOp({
@@ -3693,7 +3695,7 @@ void DecisionTreeGen::generate_branches_Slice(
// TODO: Binary search instead.
for( const auto& branch : branches.fixed_arms )
{
- auto val_des = m_builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::Constant(static_cast<uint64_t>(branch.first)));
+ auto val_des = m_builder.lvalue_or_temp(sp, ::HIR::CoreType::Usize, ::MIR::Constant::make_Uint({ static_cast<uint64_t>(branch.first), ::HIR::CoreType::Usize }));
// Special case - final just does equality
if( &branch == &branches.fixed_arms.back() )
diff --git a/src/mir/mir.cpp b/src/mir/mir.cpp
index aab0c53f..6ae5808b 100644
--- a/src/mir/mir.cpp
+++ b/src/mir/mir.cpp
@@ -11,17 +11,17 @@ namespace MIR {
::std::ostream& operator<<(::std::ostream& os, const Constant& v) {
TU_MATCHA( (v), (e),
(Int,
- os << (e < 0 ? "-" : "+");
- os << (e < 0 ? -e : e);
+ os << (e.v < 0 ? "-" : "+");
+ os << (e.v < 0 ? -e.v : e.v);
),
(Uint,
- os << e;
+ os << e.v;
),
(Float,
- os << e;
+ os << e.v;
),
(Bool,
- os << (e ? "true" : "false");
+ os << (e.v ? "true" : "false");
),
(Bytes,
os << "[";
@@ -56,16 +56,16 @@ namespace MIR {
return false;
TU_MATCHA( (*this,b), (ae,be),
(Int,
- return ae == be;
+ return ae.v == be.v && ae.t == be.t;
),
(Uint,
- return ae == be;
+ return ae.v == be.v && ae.t == be.t;
),
(Float,
- return ae == be;
+ return ae.v == be.v && ae.t == be.t;
),
(Bool,
- return ae == be;
+ return ae.v == be.v;
),
(Bytes,
return ae == be;
diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp
index d2d75e1c..aed7e2fc 100644
--- a/src/mir/mir.hpp
+++ b/src/mir/mir.hpp
@@ -91,10 +91,21 @@ enum class eUniOp
// Compile-time known values
TAGGED_UNION_EX(Constant, (), Int, (
- (Int, ::std::int64_t), // TODO: Include eCoreType
- (Uint, ::std::uint64_t), // TODO: Include eCoreType
- (Float, double),
- (Bool, bool),
+ (Int, struct {
+ ::std::int64_t v;
+ ::HIR::CoreType t;
+ }),
+ (Uint, struct {
+ ::std::uint64_t v;
+ ::HIR::CoreType t;
+ }),
+ (Float, struct {
+ double v;
+ ::HIR::CoreType t;
+ }),
+ (Bool, struct {
+ bool v; // NOTE: Defensive to prevent implicit casts
+ }),
(Bytes, ::std::vector< ::std::uint8_t>), // Byte string
(StaticString, ::std::string), // String
(Const, struct { ::HIR::Path p; }), // `const`
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp
index e487cade..b29ce728 100644
--- a/src/mir/optimise.cpp
+++ b/src/mir/optimise.cpp
@@ -1594,7 +1594,7 @@ bool MIR_Optimise_ConstPropagte(::MIR::TypeResolve& state, ::MIR::Function& fcn)
if( !se.src.as_Constant().is_Bool() )
continue;
val_known = true;
- known_val = se.src.as_Constant().as_Bool();
+ known_val = se.src.as_Constant().as_Bool().v;
break;
}
else
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index 5f87e126..b02769a0 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -2788,56 +2788,54 @@ namespace {
{
TU_MATCHA( (ve), (c),
(Int,
- if( c == INT64_MIN )
+ if( c.v == INT64_MIN )
m_of << "INT64_MIN";
else
- m_of << c;
+ m_of << c.v;
),
(Uint,
- ::HIR::TypeRef tmp;
- const auto& ty = dst_ptr ? m_mir_res->get_lvalue_type(tmp, *dst_ptr) : tmp = ::HIR::CoreType::U128;
- switch(ty.m_data.as_Primitive())
+ switch(c.t)
{
case ::HIR::CoreType::U8:
- m_of << ::std::hex << "0x" << (c & 0xFF) << ::std::dec;
+ m_of << ::std::hex << "0x" << (c.v & 0xFF) << ::std::dec;
break;
case ::HIR::CoreType::U16:
- m_of << ::std::hex << "0x" << (c & 0xFFFF) << ::std::dec;
+ m_of << ::std::hex << "0x" << (c.v & 0xFFFF) << ::std::dec;
break;
case ::HIR::CoreType::U32:
- m_of << ::std::hex << "0x" << (c & 0xFFFFFFFF) << ::std::dec;
+ m_of << ::std::hex << "0x" << (c.v & 0xFFFFFFFF) << ::std::dec;
break;
case ::HIR::CoreType::U64:
case ::HIR::CoreType::U128:
case ::HIR::CoreType::Usize:
- m_of << ::std::hex << "0x" << c << ::std::dec;
+ m_of << ::std::hex << "0x" << c.v << ::std::dec;
break;
case ::HIR::CoreType::Char:
- assert(0 <= c && c <= 0x10FFFF);
- if( c < 256 ) {
- m_of << c;
+ assert(0 <= c.v && c.v <= 0x10FFFF);
+ if( c.v < 256 ) {
+ m_of << c.v;
}
else {
- m_of << ::std::hex << "0x" << c << ::std::dec;
+ m_of << ::std::hex << "0x" << c.v << ::std::dec;
}
break;
default:
- MIR_BUG(*m_mir_res, "Invalid type for UInt literal - " << ty);
+ MIR_BUG(*m_mir_res, "Invalid type for UInt literal - " << c.t);
}
),
(Float,
- if( ::std::isnan(c) ) {
+ if( ::std::isnan(c.v) ) {
m_of << "NAN";
}
- else if( ::std::isinf(c) ) {
+ else if( ::std::isinf(c.v) ) {
m_of << "INFINITY";
}
else {
- m_of << c;
+ m_of << c.v;
}
),
(Bool,
- m_of << (c ? "true" : "false");
+ m_of << (c.v ? "true" : "false");
),
(Bytes,
// TODO: Need to know the desired value for this