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.cpp81
1 files changed, 49 insertions, 32 deletions
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index ca038230..0ced3150 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -955,6 +955,7 @@ namespace {
if( te.size() > 0 )
{
m_of << "typedef struct "; emit_ctype(ty); m_of << " {\n";
+ unsigned n_fields = 0;
for(unsigned int i = 0; i < te.size(); i++)
{
m_of << "\t";
@@ -967,8 +968,13 @@ namespace {
else {
emit_ctype(te[i], FMT_CB(ss, ss << "_" << i;));
m_of << ";\n";
+ n_fields += 1;
}
}
+ if( n_fields == 0 && m_options.disallow_empty_structs )
+ {
+ m_of << "\tchar _d;\n";
+ }
m_of << "} "; emit_ctype(ty); m_of << ";\n";
}
@@ -1315,36 +1321,40 @@ namespace {
assert(1 + union_fields.size() + 1 >= repr->fields.size());
// Make the union!
// NOTE: The way the structure generation works is that enum variants are always first, so the field index = the variant index
- m_of << "\tunion {\n";
- // > First field
+ // TODO:
+ if( !this->type_is_bad_zst(repr->fields[0].ty) || ::std::any_of(union_fields.begin(), union_fields.end(), [this,repr](auto x){ return !this->type_is_bad_zst(repr->fields[x].ty); }) )
{
- m_of << "\t\t";
- const auto& ty = repr->fields[0].ty;
- if( this->type_is_bad_zst(ty) ) {
- m_of << "// ZST: " << ty << "\n";
- }
- else {
- emit_ctype( ty, FMT_CB(ss, ss << "var_0") );
- m_of << ";\n";
- //sized_fields ++;
+ m_of << "\tunion {\n";
+ // > First field
+ {
+ m_of << "\t\t";
+ const auto& ty = repr->fields[0].ty;
+ if( this->type_is_bad_zst(ty) ) {
+ m_of << "// ZST: " << ty << "\n";
+ }
+ else {
+ emit_ctype( ty, FMT_CB(ss, ss << "var_0") );
+ m_of << ";\n";
+ //sized_fields ++;
+ }
}
- }
- // > All others
- for(auto idx : union_fields)
- {
- m_of << "\t\t";
+ // > All others
+ for(auto idx : union_fields)
+ {
+ m_of << "\t\t";
- const auto& ty = repr->fields[idx].ty;
- if( this->type_is_bad_zst(ty) ) {
- m_of << "// ZST: " << ty << "\n";
- }
- else {
- emit_ctype( ty, FMT_CB(ss, ss << "var_" << idx) );
- m_of << ";\n";
- //sized_fields ++;
+ const auto& ty = repr->fields[idx].ty;
+ if( this->type_is_bad_zst(ty) ) {
+ m_of << "// ZST: " << ty << "\n";
+ }
+ else {
+ emit_ctype( ty, FMT_CB(ss, ss << "var_" << idx) );
+ m_of << ";\n";
+ //sized_fields ++;
+ }
}
+ m_of << "\t} DATA;\n";
}
- m_of << "\t} DATA;\n";
if( repr->fields.size() == 1 + union_fields.size() )
{
@@ -1450,7 +1460,7 @@ namespace {
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 << "\tbreak;\n";
+ m_of << "\t\tbreak;\n";
}
m_of << "\t}\n";
}
@@ -1791,14 +1801,14 @@ namespace {
m_of << "{";
const auto& ity = get_inner_type(e.idx, 0);
if( this->type_is_bad_zst(ity) ) {
- m_of << " {}";
+ //m_of << " {}";
}
else {
m_of << " { .var_" << e.idx << " = ";
emit_literal(ity, *e.val, params);
- m_of << " }";
+ m_of << " }, ";
}
- m_of << ", .TAG = "; emit_enum_variant_val(repr, e.idx);
+ m_of << ".TAG = "; emit_enum_variant_val(repr, e.idx);
m_of << "}";
}
),
@@ -3991,13 +4001,15 @@ namespace {
m_of << name << o_before << "8" << o_after << "(";
break;
case ::HIR::CoreType::U16:
+ case ::HIR::CoreType::I16:
m_of << name << o_before << "16" << o_after << "(";
break;
case ::HIR::CoreType::U32:
+ case ::HIR::CoreType::I32:
m_of << name << o_before << o_after << "(";
break;
case ::HIR::CoreType::U64:
- //case ::HIR::CoreType::I64:
+ case ::HIR::CoreType::I64:
m_of << name << o_before << "64" << o_after << "(";
break;
case ::HIR::CoreType::Usize:
@@ -4987,9 +4999,14 @@ namespace {
{
case MetadataType::None:
- if( this->type_is_bad_zst(ty) && slot.is_Field() )
+ if( this->type_is_bad_zst(ty) && (slot.is_Field() || slot.is_Downcast()) )
{
- m_of << indent << Trans_Mangle(p) << "((void*)&"; emit_lvalue(*slot.as_Field().val); m_of << ");\n";
+ m_of << indent << Trans_Mangle(p) << "((void*)&";
+ if( slot.is_Field() )
+ emit_lvalue(*slot.as_Field().val);
+ else
+ emit_lvalue(*slot.as_Downcast().val);
+ m_of << ");\n";
}
else
{