diff options
Diffstat (limited to 'gcc/cp')
| -rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
| -rw-r--r-- | gcc/cp/decl.c | 12 | ||||
| -rw-r--r-- | gcc/cp/decl2.c | 32 | ||||
| -rw-r--r-- | gcc/cp/friend.c | 5 | ||||
| -rw-r--r-- | gcc/cp/pt.c | 4 |
5 files changed, 40 insertions, 15 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c3c7c868e25..37170e2ca71 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3721,7 +3721,7 @@ extern void maybe_make_one_only (tree); 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); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 1b788310ca3..17b625f668c 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3727,8 +3727,10 @@ start_decl (tree declarator, 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; } @@ -5691,8 +5693,10 @@ grokfndecl (tree ctype, 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 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index e094493f988..5730d369efc 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -612,15 +612,19 @@ check_java_method (tree method) /* 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 @@ -638,9 +642,20 @@ check_classfn (tree ctype, tree function, bool template_header_p) 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 : @@ -684,6 +699,9 @@ check_classfn (tree ctype, tree function, bool template_header_p) 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) diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index c81bd934e0a..e55adaa8bc0 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -397,7 +397,10 @@ do_friend (tree ctype, tree declarator, tree decl, 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); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5d2c95ac155..96ee6875a56 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5142,8 +5142,8 @@ tsubst_friend_function (tree decl, tree args) { /* 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; |

