summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/trans/codegen.cpp4
-rw-r--r--src/trans/codegen.hpp1
-rw-r--r--src/trans/codegen_c.cpp5
-rw-r--r--src/trans/enumerate.cpp17
-rw-r--r--src/trans/trans_list.hpp4
5 files changed, 25 insertions, 6 deletions
diff --git a/src/trans/codegen.cpp b/src/trans/codegen.cpp
index 29b42325..0141497f 100644
--- a/src/trans/codegen.cpp
+++ b/src/trans/codegen.cpp
@@ -47,6 +47,10 @@ void Trans_Codegen(const ::std::string& outfile, const ::HIR::Crate& crate, cons
codegen->emit_type(ty.first);
}
}
+ for(const auto& ty : list.m_typeids)
+ {
+ codegen->emit_type_id(ty);
+ }
// 2. Emit function prototypes
for(const auto& ent : list.m_functions)
diff --git a/src/trans/codegen.hpp b/src/trans/codegen.hpp
index e24fdb13..040449bf 100644
--- a/src/trans/codegen.hpp
+++ b/src/trans/codegen.hpp
@@ -32,6 +32,7 @@ public:
// - Inner-most types are visited first.
virtual void emit_type_proto(const ::HIR::TypeRef& ) {}
virtual void emit_type(const ::HIR::TypeRef& ) {}
+ virtual void emit_type_id(const ::HIR::TypeRef& ) {}
// Called when a TypeRef::Path is encountered (after visiting inner types)
virtual void emit_struct(const Span& sp, const ::HIR::GenericPath& p, const ::HIR::Struct& item) {}
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index 11a8b9b9..12c80a88 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -195,6 +195,10 @@ namespace {
m_mir_res = nullptr;
}
+ void emit_type_id(const ::HIR::TypeRef& ty) override
+ {
+ m_of << "tTYPEID __typeid_" << Trans_Mangle(ty) << " __attribute__((weak));\n";
+ }
void emit_type_proto(const ::HIR::TypeRef& ty) override
{
TRACE_FUNCTION_F(ty);
@@ -288,7 +292,6 @@ namespace {
else {
}
- m_of << "tTYPEID __typeid_" << Trans_Mangle(ty) << ";\n";
m_mir_res = nullptr;
}
diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp
index a6d3edab..d3f761d2 100644
--- a/src/trans/enumerate.cpp
+++ b/src/trans/enumerate.cpp
@@ -594,6 +594,7 @@ void Trans_Enumerate_Types(EnumState& state)
return monomorphise_type_needed(ty) ? tmp = pp.monomorph(tv.m_resolve, ty) : ty;
};
// TODO: Handle erased types in the return type.
+ ASSERT_BUG(sp, !visit_ty_with(fcn.m_return, [](const auto& x) { return x.m_data.is_ErasedType(); }), "TODO: Erased types in enumerate");
tv.visit_type( monomorph(fcn.m_return) );
for(const auto& arg : fcn.m_args)
tv.visit_type( monomorph(arg.second) );
@@ -1258,25 +1259,27 @@ void Trans_Enumerate_FillFrom_Path(EnumState& state, const ::HIR::Path& path, co
BUG(sp, "Item not found for " << path_mono);
),
(AutoGenerate,
- // This is returned either if the item is <T as U>::#vtable or if it's <(Trait) as Trait>::method
if( path_mono.m_data.is_Generic() )
{
// Leave generation of struct/enum constructors to codgen
+ // TODO: Add to a list of required constructors
}
- else if( path_mono.m_data.as_UfcsKnown().item == "#vtable" )
+ // - <T as U>::#vtable
+ else if( path_mono.m_data.is_UfcsKnown() && path_mono.m_data.as_UfcsKnown().item == "#vtable" )
{
if( state.rv.add_vtable( path_mono.clone(), {} ) )
{
- // TODO: Add the vtable type to enumerte list?
// Fill from the vtable
Trans_Enumerate_FillFrom_VTable(state, mv$(path_mono), sub_pp);
}
}
- else if( path_mono.m_data.as_UfcsKnown().type->m_data.is_TraitObject() )
+ // - <(Trait) as Trait>::method
+ else if( path_mono.m_data.is_UfcsKnown() && path_mono.m_data.as_UfcsKnown().type->m_data.is_TraitObject() )
{
// Must have been a dynamic dispatch request, just leave as-is
}
- else if( path_mono.m_data.as_UfcsKnown().type->m_data.is_Function() )
+ // - <fn(...) as Fn*>::call*
+ else if( path_mono.m_data.is_UfcsKnown() && path_mono.m_data.as_UfcsKnown().type->m_data.is_Function() )
{
// Must have been a dynamic dispatch request, just leave as-is
}
@@ -1441,6 +1444,10 @@ void Trans_Enumerate_FillFrom_MIR(EnumState& state, const ::MIR::Function& code,
Trans_Enumerate_FillFrom_Path(state, e2, pp);
),
(Intrinsic,
+ if( e2.name == "type_id" ) {
+ // Add <T>::#type_id to the enumerate list
+ state.rv.m_typeids.insert( pp.monomorph(state.crate, e2.params.m_types.at(0)) );
+ }
)
)
for(const auto& arg : e.args)
diff --git a/src/trans/trans_list.hpp b/src/trans/trans_list.hpp
index eed91551..86284172 100644
--- a/src/trans/trans_list.hpp
+++ b/src/trans/trans_list.hpp
@@ -58,6 +58,10 @@ public:
::std::map< ::HIR::Path, ::std::unique_ptr<TransList_Function> > m_functions;
::std::map< ::HIR::Path, ::std::unique_ptr<TransList_Static> > m_statics;
::std::map< ::HIR::Path, Trans_Params> m_vtables;
+ /// Required type_id values
+ ::std::set< ::HIR::TypeRef> m_typeids;
+ /// Required struct/enum constructor impls
+ ::std::set< ::HIR::GenericPath> m_constructors;
// .second is `true` if this is a from a reference to the type
::std::vector< ::std::pair<::HIR::TypeRef, bool> > m_types;