extern int more_specialized PARAMS ((tree, tree, tree));
extern void mark_class_instantiated PARAMS ((tree, int));
extern void do_decl_instantiation PARAMS ((tree, tree, tree));
-extern void do_type_instantiation PARAMS ((tree, tree));
+extern void do_type_instantiation PARAMS ((tree, tree, int));
extern tree instantiate_decl PARAMS ((tree, int));
extern tree get_bindings PARAMS ((tree, tree, tree));
extern void add_tree PARAMS ((tree));
explicit_instantiation:
TEMPLATE begin_explicit_instantiation typespec ';'
- { do_type_instantiation ($3.t, NULL_TREE);
+ { do_type_instantiation ($3.t, NULL_TREE, 1);
yyungetc (';', 1); }
end_explicit_instantiation
| TEMPLATE begin_explicit_instantiation typed_declspecs declarator
{ do_decl_instantiation (NULL_TREE, $3, NULL_TREE); }
end_explicit_instantiation
| SCSPEC TEMPLATE begin_explicit_instantiation typespec ';'
- { do_type_instantiation ($4.t, $1);
+ { do_type_instantiation ($4.t, $1, 1);
yyungetc (';', 1); }
end_explicit_instantiation
| SCSPEC TEMPLATE begin_explicit_instantiation typed_declspecs
}
}
+/* Perform an explicit instantiation of template class T. STORAGE, if
+ non-null, is the RID for extern, inline or static. COMPLAIN is
+ non-zero if this is called from the parser, zero if called recursively,
+ since the standard is unclear (as detailed below). */
+
void
-do_type_instantiation (t, storage)
+do_type_instantiation (t, storage, complain)
tree t, storage;
+ int complain;
{
int extern_p = 0;
int nomem_p = 0;
if (!COMPLETE_TYPE_P (t))
{
- cp_error ("explicit instantiation of `%#T' before definition of template",
- t);
+ if (complain)
+ cp_error ("explicit instantiation of `%#T' before definition of template",
+ t);
return;
}
No program shall both explicitly instantiate and explicitly
specialize a template. */
- cp_error ("explicit instantiation of `%#T' after", t);
- cp_error_at ("explicit specialization here", t);
+ if (complain)
+ {
+ cp_error ("explicit instantiation of `%#T' after", t);
+ cp_error_at ("explicit specialization here", t);
+ }
return;
}
else if (CLASSTYPE_EXPLICIT_INSTANTIATION (t))
was `extern'. If EXTERN_P then the second is. If -frepo, chances
are we already got marked as an explicit instantion because of the
repo file. All these cases are OK. */
- if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository)
+ if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository
+ && complain)
cp_pedwarn ("duplicate explicit instantiation of `%#T'", t);
/* If we've already instantiated the template, just return now. */
for (tmp = CLASSTYPE_TAGS (t); tmp; tmp = TREE_CHAIN (tmp))
if (IS_AGGR_TYPE (TREE_VALUE (tmp))
&& !uses_template_parms (CLASSTYPE_TI_ARGS (TREE_VALUE (tmp))))
- do_type_instantiation (TYPE_MAIN_DECL (TREE_VALUE (tmp)), storage);
+ do_type_instantiation (TYPE_MAIN_DECL (TREE_VALUE (tmp)), storage, 0);
}
}