OSDN Git Service

cp/
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl2.c
index 8b39b81..a6187e2 100644 (file)
@@ -553,7 +553,8 @@ check_classfn (tree ctype, tree function, tree template_parms)
 {
   int ix;
   bool is_template;
-
+  tree pushed_scope;
+  
   if (DECL_USE_TEMPLATE (function)
       && !(TREE_CODE (function) == TEMPLATE_DECL
           && DECL_TEMPLATE_SPECIALIZATION (function))
@@ -583,16 +584,18 @@ check_classfn (tree ctype, tree function, tree template_parms)
   /* OK, is this a definition of a member template?  */
   is_template = (template_parms != NULL_TREE);
 
+  /* We must enter the scope here, because conversion operators are
+     named by target type, and type equivalence relies on typenames
+     resolving within the scope of CTYPE.  */
+  pushed_scope = push_scope (ctype);
   ix = class_method_index_for_fn (complete_type (ctype), function);
   if (ix >= 0)
     {
       VEC(tree,gc) *methods = CLASSTYPE_METHOD_VEC (ctype);
       tree fndecls, fndecl = 0;
       bool is_conv_op;
-      tree pushed_scope;
       const char *format = NULL;
 
-      pushed_scope = push_scope (ctype);
       for (fndecls = VEC_index (tree, methods, ix);
           fndecls; fndecls = OVL_NEXT (fndecls))
        {
@@ -631,10 +634,13 @@ check_classfn (tree ctype, tree function, tree template_parms)
                      == DECL_TI_TEMPLATE (fndecl))))
            break;
        }
-      if (pushed_scope)
-       pop_scope (pushed_scope);
       if (fndecls)
-       return OVL_CURRENT (fndecls);
+       {
+         if (pushed_scope)
+           pop_scope (pushed_scope);
+         return OVL_CURRENT (fndecls);
+       }
+      
       error ("prototype for %q#D does not match any in class %qT",
             function, ctype);
       is_conv_op = DECL_CONV_FN_P (fndecl);
@@ -682,6 +688,9 @@ check_classfn (tree ctype, tree function, tree template_parms)
      properly within the class.  */
   if (COMPLETE_TYPE_P (ctype))
     add_method (ctype, function, NULL_TREE);
+  
+  if (pushed_scope)
+    pop_scope (pushed_scope);
   return NULL_TREE;
 }
 
@@ -1753,20 +1762,24 @@ determine_visibility (tree decl)
                    ? TYPE_TEMPLATE_INFO (TREE_TYPE (decl))
                    : DECL_TEMPLATE_INFO (decl));
       tree args = TI_ARGS (tinfo);
-      int depth = TMPL_ARGS_DEPTH (args);
-      tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo));
-
-      if (!DECL_VISIBILITY_SPECIFIED (decl))
+      
+      if (args != error_mark_node)
        {
-         DECL_VISIBILITY (decl) = DECL_VISIBILITY (pattern);
-         DECL_VISIBILITY_SPECIFIED (decl)
-           = DECL_VISIBILITY_SPECIFIED (pattern);
-       }
+         int depth = TMPL_ARGS_DEPTH (args);
+         tree pattern = DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo));
 
-      /* FIXME should TMPL_ARGS_DEPTH really return 1 for null input? */
-      if (args && depth > template_class_depth (class_type))
-       /* Limit visibility based on its template arguments.  */
-       constrain_visibility_for_template (decl, args);
+         if (!DECL_VISIBILITY_SPECIFIED (decl))
+           {
+             DECL_VISIBILITY (decl) = DECL_VISIBILITY (pattern);
+             DECL_VISIBILITY_SPECIFIED (decl)
+               = DECL_VISIBILITY_SPECIFIED (pattern);
+           }
+
+         /* FIXME should TMPL_ARGS_DEPTH really return 1 for null input? */
+         if (args && depth > template_class_depth (class_type))
+           /* Limit visibility based on its template arguments.  */
+           constrain_visibility_for_template (decl, args);
+       }
     }
 
   if (class_type)
@@ -3481,6 +3494,8 @@ mark_used (tree decl)
     }
 
   TREE_USED (decl) = 1;
+  if (DECL_CLONED_FUNCTION_P (decl))
+    TREE_USED (DECL_CLONED_FUNCTION (decl)) = 1;
   /* If we don't need a value, then we don't need to synthesize DECL.  */
   if (skip_evaluation)
     return;