diff options
-rw-r--r-- | src/trans/codegen.cpp | 4 | ||||
-rw-r--r-- | src/trans/codegen.hpp | 1 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 5 | ||||
-rw-r--r-- | src/trans/enumerate.cpp | 17 | ||||
-rw-r--r-- | src/trans/trans_list.hpp | 4 |
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; |