This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH to no_linkage_check and related code


richi pointed out to me in IRC today that my semi-recent change to no_linkage_check was killing performance on the testcase from PR 29433. It turns out that since I started just clearing TREE_PUBLIC on types with no linkage, there's no need to look at template arguments, which is what was causing the trouble.

While I was thinking about that, I also improved the handling of lambdas, eliminating the ugly callback into the parser.

Tested x86_64-pc-linux-gnu, applied to trunk.

commit 47017b14465e3ab598803d790acf815e0f99ee99
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Oct 1 17:43:04 2009 -0400

    	* parser.c (cp_parser_lambda_expression): Compute visibility.
    	(no_linkage_lambda_type_p): Remove.
    	* cp-tree.h: Remove declaration.
    	* tree.c (no_linkage_check): Don't call it.  Don't check template
    	args.  Don't check TREE_PUBLIC Types.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index ab4a6a7..fc00176 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5303,9 +5303,6 @@ extern tree cxx_omp_clause_dtor			(tree, tree);
 extern void cxx_omp_finish_clause		(tree);
 extern bool cxx_omp_privatize_by_reference	(const_tree);
 
-/* in parser.c */
-extern bool no_linkage_lambda_type_p		(tree);
-
 /* -- end of C++ */
 
 #endif /* ! GCC_CP_TREE_H */
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 950d136..210d3dd 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7005,31 +7005,6 @@ finish_lambda_scope (void)
   VEC_pop (tree_int, lambda_scope_stack);
 }
 
-/* We want to determine the linkage of a lambda type at pushtag time,
-   before CLASSTYPE_LAMBDA_EXPR has been set.  So this callback allows us
-   to find out whether the current lambda mangling scope will give us
-   linkage or not.  */
-
-bool
-no_linkage_lambda_type_p (tree type)
-{
-  tree lambda, scope;
-  if (!LAMBDA_TYPE_P (type))
-    return false;
-
-  lambda = CLASSTYPE_LAMBDA_EXPR (type);
-  if (lambda)
-    scope = LAMBDA_EXPR_EXTRA_SCOPE (lambda);
-  else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
-    /* We can't use lambda_scope, and CLASSTYPE_TEMPLATE_INFO won't be set
-       yet either, so guess it's public for now.  */
-    return false;
-  else
-    scope = lambda_scope;
-
-  return (scope == NULL_TREE);
-}
-
 /* Parse a lambda expression.
 
    lambda-expression:
@@ -7054,6 +7029,9 @@ cp_parser_lambda_expression (cp_parser* parser)
 
   record_lambda_scope (lambda_expr);
 
+  /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set.  */
+  determine_visibility (TYPE_NAME (type));
+
   {
     /* Inside the class, surrounding template-parameter-lists do not apply.  */
     unsigned int saved_num_template_parameter_lists
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 19a1270..1cd2bf5 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1556,46 +1556,41 @@ no_linkage_check (tree t, bool relaxed_p)
     case RECORD_TYPE:
       if (TYPE_PTRMEMFUNC_P (t))
 	goto ptrmem;
+      /* Lambda types that don't have mangling scope have no linkage.  We
+	 check CLASSTYPE_LAMBDA_EXPR here rather than LAMBDA_TYPE_P because
+	 when we get here from pushtag none of the lambda information is
+	 set up yet, so we want to assume that the lambda has linkage and
+	 fix it up later if not.  */
+      if (CLASSTYPE_LAMBDA_EXPR (t)
+	  && LAMBDA_TYPE_EXTRA_SCOPE (t) == NULL_TREE)
+	return t;
       /* Fall through.  */
     case UNION_TYPE:
       if (!CLASS_TYPE_P (t))
 	return NULL_TREE;
-
-      /* Check template type-arguments.  I think that types with no linkage
-         can't occur in non-type arguments, though that might change with
-         constexpr.  */
-      r = CLASSTYPE_TEMPLATE_INFO (t);
-      if (r)
-	{
-	  tree args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (r));
-	  int i;
-
-	  for (i = TREE_VEC_LENGTH (args); i-- > 0; )
-	    {
-	      tree elt = TREE_VEC_ELT (args, i);
-	      if (TYPE_P (elt)
-		  && (r = no_linkage_check (elt, relaxed_p), r))
-		return r;
-	    }
-	}
       /* Fall through.  */
     case ENUMERAL_TYPE:
       /* Only treat anonymous types as having no linkage if they're at
 	 namespace scope.  This doesn't have a core issue number yet.  */
       if (TYPE_ANONYMOUS_P (t) && TYPE_NAMESPACE_SCOPE_P (t))
 	return t;
-      if (no_linkage_lambda_type_p (t))
-	return t;
 
-      r = CP_TYPE_CONTEXT (t);
-      if (TYPE_P (r))
-	return no_linkage_check (TYPE_CONTEXT (t), relaxed_p);
-      else if (TREE_CODE (r) == FUNCTION_DECL)
+      for (r = CP_TYPE_CONTEXT (t); ; )
 	{
-	  if (!relaxed_p || !TREE_PUBLIC (r) || !vague_linkage_fn_p (r))
-	    return t;
+	  /* If we're a nested type of a !TREE_PUBLIC class, we might not
+	     have linkage, or we might just be in an anonymous namespace.
+	     If we're in a TREE_PUBLIC class, we have linkage.  */
+	  if (TYPE_P (r) && !TREE_PUBLIC (TYPE_NAME (r)))
+	    return no_linkage_check (TYPE_CONTEXT (t), relaxed_p);
+	  else if (TREE_CODE (r) == FUNCTION_DECL)
+	    {
+	      if (!relaxed_p || !vague_linkage_fn_p (r))
+		return t;
+	      else
+		r = CP_DECL_CONTEXT (r);
+	    }
 	  else
-	    return no_linkage_check (CP_DECL_CONTEXT (r), relaxed_p);
+	    break;
 	}
 
       return NULL_TREE;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]