extern void grokclassfn (tree, tree, enum overload_flags, tree);
extern tree grok_array_decl (tree, tree);
extern tree delete_sanity (tree, tree, bool, int);
-extern tree check_classfn (tree, tree, bool);
+extern tree check_classfn (tree, tree, tree);
extern void check_member_template (tree);
extern tree grokfield (tree, tree, tree, tree, tree);
extern tree grokbitfield (tree, tree, tree);
else
{
tree field = check_classfn (context, decl,
- processing_template_decl
- > template_class_depth (context));
+ (processing_template_decl
+ > template_class_depth (context))
+ ? current_template_parms
+ : NULL_TREE);
if (field && duplicate_decls (decl, field))
decl = field;
}
tree old_decl;
old_decl = check_classfn (ctype, decl,
- processing_template_decl
- > template_class_depth (ctype));
+ (processing_template_decl
+ > template_class_depth (ctype))
+ ? current_template_parms
+ : NULL_TREE);
if (old_decl && TREE_CODE (old_decl) == TEMPLATE_DECL)
/* Because grokfndecl is always supposed to return a
/* Sanity check: report error if this function FUNCTION is not
really a member of the class (CTYPE) it is supposed to belong to.
- CNAME is the same here as it is for grokclassfn above.
- TEMPLATE_HEADER_P is true when this declaration comes with a
- template header. */
+ TEMPLATE_PARMS is used to specifiy the template parameters of a member
+ template passed as FUNCTION_DECL. If the member template is passed as a
+ TEMPLATE_DECL, it can be NULL since the parameters can be extracted
+ from the declaration. If the function is not a function template, it
+ must be NULL.
+ It returns the original declaration for the function, or NULL_TREE
+ if no declaration was found (and an error was emitted). */
tree
-check_classfn (tree ctype, tree function, bool template_header_p)
+check_classfn (tree ctype, tree function, tree template_parms)
{
int ix;
- int is_template;
+ bool is_template;
if (DECL_USE_TEMPLATE (function)
&& !(TREE_CODE (function) == TEMPLATE_DECL
find the method, but we don't complain. */
return NULL_TREE;
+ /* Basic sanity check: for a template function, the template parameters
+ either were not passed, or they are the same of DECL_TEMPLATE_PARMS. */
+ if (TREE_CODE (function) == TEMPLATE_DECL)
+ {
+ my_friendly_assert (!template_parms
+ || comp_template_parms
+ (template_parms,
+ DECL_TEMPLATE_PARMS (function)),
+ 20040303);
+ template_parms = DECL_TEMPLATE_PARMS (function);
+ }
+
/* OK, is this a definition of a member template? */
- is_template = (TREE_CODE (function) == TEMPLATE_DECL
- || template_header_p);
+ is_template = (template_parms != NULL_TREE);
ix = lookup_fnfields_1 (complete_type (ctype),
DECL_CONSTRUCTOR_P (function) ? ctor_identifier :
if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
TREE_TYPE (TREE_TYPE (fndecl)))
&& compparms (p1, p2)
+ && (!is_template
+ || comp_template_parms (template_parms,
+ DECL_TEMPLATE_PARMS (fndecl)))
&& (DECL_TEMPLATE_SPECIALIZATION (function)
== DECL_TEMPLATE_SPECIALIZATION (fndecl))
&& (!DECL_TEMPLATE_SPECIALIZATION (function)
validity of the declaration later. */
decl = push_template_decl_real (decl, /*is_friend=*/1);
else
- decl = check_classfn (ctype, decl, template_member_p);
+ decl = check_classfn (ctype, decl,
+ template_member_p
+ ? current_template_parms
+ : NULL_TREE);
if (template_member_p && decl && TREE_CODE (decl) == FUNCTION_DECL)
decl = DECL_TI_TEMPLATE (decl);
{
/* Check to see that the declaration is really present, and,
possibly obtain an improved declaration. */
- tree fn = check_classfn (DECL_CONTEXT (new_friend),
- new_friend, false);
+ tree fn = check_classfn (DECL_CONTEXT (new_friend),
+ new_friend, NULL_TREE);
if (fn)
new_friend = fn;
+2004-05-03 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14389
+ * g++.dg/template/member5.C: New test.
+
2004-05-03 Uros Bizjak <uros@kss-loka.si>
- * gcc.dg/builtins-34.c: Also check expm1*.
+ * gcc.dg/builtins-34.c: Also check expm1*.
2004-05-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
--- /dev/null
+// { dg-do compile }
+// Contributed by: <fasbjx at free dot fr>
+// PR c++/14389: Disambiguate overloaded member templates which differ only
+// in the template argument list.
+
+namespace N1 {
+
+struct S {
+ template< typename B, typename A > void foo();
+ template< typename A > void foo();
+};
+
+template< typename A > void S::foo() {}
+template< typename B, typename A > void S::foo() {}
+
+template void S::foo<void> ();
+template void S::foo<void,void> ();
+
+}
+
+namespace N2 {
+
+struct S {
+ template< typename _A > void foo();
+ template< int _i > void foo();
+};
+
+template< typename _A > void S::foo() {}
+
+template void S::foo< 0 >(); // { dg-error "no definition available|instantiated from here" }
+
+}