1999-02-26 Mark Mitchell <mark@markmitchell.com>
+ * decl.c (duplicate_decls): Copy DECL_TEMPLATE_INSTANTIATED when
+ merging decls.
+ * pt.c (regenerate_decl_from_template): Tweak for clarity.
+ (instantiate_decl): Mark a decl instantiated before regenerating
+ it to avoid recursion.
+ * tree.c (mapcar): Don't call decl_constant_value unless we know
+ something is TREE_READONLY_DECL_P.
+
* class.c (check_for_override): Don't stop checking when we find
the first overridden function. Delete #if 0'd code.
* search.c (get_matching_virtual): Likewise.
DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl);
DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl);
DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
+ DECL_TEMPLATE_INSTANTIATED (newdecl)
+ |= DECL_TEMPLATE_INSTANTIATED (olddecl);
/* Don't really know how much of the language-specific
values we should copy from old to new. */
DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
/* Pop the class context we pushed above. */
popclass (1);
}
-
- if (TREE_CODE (decl) == FUNCTION_DECL)
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
{
/* Convince duplicate_decls to use the DECL_ARGUMENTS from the
new decl. */
goto out;
}
- regenerate_decl_from_template (d, td);
+ /* We're now committed to instantiating this template. Mark it as
+ instantiated so that recursive calls to instantiate_decl do not
+ try to instantiate it again. */
DECL_TEMPLATE_INSTANTIATED (d) = 1;
+ /* Regenerate the declaration in case the template has been modified
+ by a subsequent redeclaration. */
+ regenerate_decl_from_template (d, td);
+
/* We already set the file and line above. Reset them now in case
they changed as a result of calling regenerate_decl_from_template. */
lineno = DECL_SOURCE_LINE (d);
void g() { const int i = 7; f<i>(7); }
however, we must actually return the constant initializer. */
- tmp = decl_constant_value (t);
- if (tmp != t)
- return mapcar (tmp, func);
- else
- return error_mark_node;
+ if (TREE_READONLY_DECL_P (t))
+ {
+ tmp = decl_constant_value (t);
+ if (tmp != t)
+ return mapcar (tmp, func);
+ }
+ return error_mark_node;
case PARM_DECL:
{
--- /dev/null
+// Build don't link:
+// Origin: Steven Parkes <parkes@sierravista.com>
+
+typedef unsigned int size_t;
+
+class UUId {};
+
+template <class T> class MetaClass;
+
+class TypeInfo;
+
+struct MetaClassGeneric
+{
+ MetaClassGeneric( TypeInfo& );
+};
+
+struct TypeInfo
+{
+ void (*constructor)( void* );
+ void initialize( void* );
+};
+
+template <class T>
+class TypeIDInit {
+public:
+ TypeIDInit();
+ static void initialize();
+ static TypeInfo info;
+ static int storage[];
+ static void metaclassConstructor( void* );
+};
+
+template <class T>
+TypeInfo TypeIDInit<T>::info =
+{
+ TypeIDInit<T>::metaclassConstructor
+};
+
+template <class T>
+inline
+TypeIDInit<T>::TypeIDInit()
+{
+ info.initialize(storage);
+}
+
+template <class T>
+class NameInfo : public MetaClassGeneric {
+public:
+ NameInfo()
+ : MetaClassGeneric( TypeIDInit<T>::info ) {}
+};
+
+class MetaClass<UUId>
+: public NameInfo<UUId>
+{
+};
+
+extern "C++"
+inline void *operator new(size_t, void *place) throw() { return place; }
+
+template <class T>
+void
+TypeIDInit<T>::metaclassConstructor( void* place )
+{
+ new ( place ) MetaClass<T>;
+}
+
+template class TypeIDInit<UUId> ;
+