[Release b] <t4m_bug_nonexpctor> Mon Jul 12 18:03:18 WEST 2004 In the current release of tendra4minix (a), after fixing <t4m_bug_usage>, the program nonexpctor.C produces this error, "nonexpctor.C", line 14: Error: [ISO 14]: The non-exported template 'Alloc < Thread >::Alloc ()' has not been defined. It is ERR_temp_decl_undef, and it's being reported in function copy_template [instance.c]. The error disappears when we put a definition (inline or not) for this constructor before the declaration of class Process. For example, changing 'Alloc();' for 'Alloc() {}'. The error also dissapears when there is no declaration for the default constructor. The problem is in function export_template [template.c], it cannot deal with overloaded functions. In the program nonexpctor.C, it is exporting the copy constructor 'Alloc::Alloc(const Alloc<T> &)', but not the rest of the list of overloaded constructors; the default constructor happens to be second in that list, since it was declared first. To fix this bug, we can write a new static function named export_templ_over in file template.c for recursing into the list of overloaded functions of a member of an exported template class, /* EXPORT AN OVERLOADED FUNCTION TEMPLATE IDENTIFIER This routine marks the overloaded function template identifier id as having been exported. def is 2 for the first explicit declaration of a template, 1 for a redeclaration and 0 otherwise. This function is used only by export_template, for recursing into lists of overloaded member function identifiers. */ static void export_template_over PROTO_N ( ( id, def ) ) PROTO_T ( IDENTIFIER id X int def ) { if ( IS_id_function_etc ( id ) ) { IDENTIFIER oid = DEREF_id ( id_function_etc_over ( id ) ) ; if ( !IS_NULL_id ( oid ) ) export_template_over ( oid, def ) ; } export_template ( id, def ) ; } Then, in function export_template [template.c], in cases id_class_name_tag, id_class_alias_tag, we change the calls to export_template for calls to export_template_over, that is, we change /* Scan through class members */ IDENTIFIER pid = DEREF_id ( member_id ( mem ) ) ; IDENTIFIER qid = DEREF_id ( member_alt ( mem ) ) ; if ( !IS_NULL_id ( pid ) ) { export_template ( pid, def ) ; } if ( !IS_NULL_id ( qid ) && !EQ_id ( qid, pid ) ) { export_template ( qid, def ) ; } for /* Scan through class members */ IDENTIFIER pid = DEREF_id ( member_id ( mem ) ) ; IDENTIFIER qid = DEREF_id ( member_alt ( mem ) ) ; if ( !IS_NULL_id ( pid ) ) { export_template_over ( pid, def ) ; } if ( !IS_NULL_id ( qid ) && !EQ_id ( qid, pid ) ) { export_template_over ( qid, def ) ; } Observe that overloading is not dealt with in the case of non-member template functions, since they are unrelated to each other and are exported separately.