public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++ PATCH] namespace bindings
@ 2017-05-23 19:47 Nathan Sidwell
  0 siblings, 0 replies; 10+ messages in thread
From: Nathan Sidwell @ 2017-05-23 19:47 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 127 bytes --]

There's a twisty set of function calling to get at a namespace binding. 
This patch cleans that up.

nathan
-- 
Nathan Sidwell

[-- Attachment #2: ns-bind.diff --]
[-- Type: text/x-patch, Size: 9067 bytes --]

2017-05-23  Nathan Sidwell  <nathan@acm.org>

	* name-lookup.c (find_namespace_binding): New.
	(pushdecl_maybe_friend_1): Use CP_DECL_CONTEXT.
	(set_identifier_type_value_with_scope): Use find_namespace_binding.
	(find_binding, cp_binding_level_find_binding_for_name,
	binding_for_name, namespace_binding_1): Delete.
	(push_overloaded_decl_1): Use CP_DECL_CONTEXT.
	(get_namespace_binding, set_namespace_binding,
	finish_namespace_using_decl, unqualified_namespace_lookup_1,
	qualified_lookup_using_namespace, lookup_type_scope_1,
	lookup_name_innermost_nonclass_level_1): Use find_namespace_binding.

Index: name-lookup.c
===================================================================
--- name-lookup.c	(revision 248377)
+++ name-lookup.c	(working copy)
@@ -48,7 +48,6 @@ struct scope_binding {
 };
 #define EMPTY_SCOPE_BINDING { NULL_TREE, NULL_TREE }
 
-static cxx_binding *binding_for_name (cp_binding_level *, tree);
 static tree push_overloaded_decl (tree, int, bool);
 static bool lookup_using_namespace (tree, struct scope_binding *, tree,
 				    tree, int);
@@ -62,6 +61,32 @@ static void consider_binding_level (tree
 static tree push_using_directive (tree);
 static void diagnose_name_conflict (tree, tree);
 
+/* Find the binding for NAME in namespace NS.  If CREATE_P is true,
+   make an empty binding if there wasn't one.  */
+
+static cxx_binding *
+find_namespace_binding (tree ns, tree name, bool create_p = false)
+{
+  cp_binding_level *level = NAMESPACE_LEVEL (ns);
+  cxx_binding *binding = IDENTIFIER_NAMESPACE_BINDINGS (name);
+
+  for (;binding; binding = binding->previous)
+    if (binding->scope == level)
+      return binding;
+
+  if (create_p)
+    {
+      binding = cxx_binding_make (NULL, NULL);
+      binding->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);
+      binding->scope = level;
+      binding->is_local = false;
+      binding->value_is_inherited = false;
+      IDENTIFIER_NAMESPACE_BINDINGS (name) = binding;
+    }
+
+  return binding;
+}
+
 /* Add DECL to the list of things declared in B.  */
 
 static void
@@ -1698,7 +1723,7 @@ pushdecl_maybe_friend_1 (tree x, bool is
       /* In case this decl was explicitly namespace-qualified, look it
 	 up in its namespace context.  */
       if (DECL_NAMESPACE_SCOPE_P (x) && namespace_bindings_p ())
-	t = get_namespace_binding (DECL_CONTEXT (x), name);
+	t = get_namespace_binding (CP_DECL_CONTEXT (x), name);
       else
 	t = lookup_name_innermost_nonclass_level (name);
 
@@ -2702,9 +2727,9 @@ set_identifier_type_value_with_scope (tr
     }
   else
     {
-      cxx_binding *binding =
-	binding_for_name (NAMESPACE_LEVEL (current_namespace), id);
-      gcc_assert (decl);
+      cxx_binding *binding
+	= find_namespace_binding (current_namespace, id, true);
+
       if (binding->value)
 	supplement_binding (binding, decl);
       else
@@ -2811,55 +2836,6 @@ make_lambda_name (void)
   return get_identifier (buf);
 }
 
-/* Return (from the stack of) the BINDING, if any, established at SCOPE.  */
-
-static inline cxx_binding *
-find_binding (cp_binding_level *scope, cxx_binding *binding)
-{
-  for (; binding != NULL; binding = binding->previous)
-    if (binding->scope == scope)
-      return binding;
-
-  return (cxx_binding *)0;
-}
-
-/* Return the binding for NAME in SCOPE, if any.  Otherwise, return NULL.  */
-
-static inline cxx_binding *
-cp_binding_level_find_binding_for_name (cp_binding_level *scope, tree name)
-{
-  cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);
-  if (b)
-    {
-      /* Fold-in case where NAME is used only once.  */
-      if (scope == b->scope && b->previous == NULL)
-	return b;
-      return find_binding (scope, b);
-    }
-  return NULL;
-}
-
-/* Always returns a binding for name in scope.  If no binding is
-   found, make a new one.  */
-
-static cxx_binding *
-binding_for_name (cp_binding_level *scope, tree name)
-{
-  cxx_binding *result;
-
-  result = cp_binding_level_find_binding_for_name (scope, name);
-  if (result)
-    return result;
-  /* Not found, make a new one.  */
-  result = cxx_binding_make (NULL, NULL);
-  result->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);
-  result->scope = scope;
-  result->is_local = false;
-  result->value_is_inherited = false;
-  IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
-  return result;
-}
-
 /* Insert another USING_DECL into the current binding level, returning
    this declaration. If this is a redeclaration, do nothing, and
    return NULL_TREE if this not in namespace scope (in namespace
@@ -2978,7 +2954,7 @@ push_overloaded_decl_1 (tree decl, int f
   int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL));
 
   if (doing_global)
-    old = get_namespace_binding (DECL_CONTEXT (decl), name);
+    old = get_namespace_binding (CP_DECL_CONTEXT (decl), name);
   else
     old = lookup_name_innermost_nonclass_level (name);
 
@@ -3965,25 +3941,6 @@ do_class_using_decl (tree scope, tree na
 }
 
 \f
-/* Return the binding value for name in scope.  */
-
-
-static tree
-namespace_binding_1 (tree scope, tree name)
-{
-  cxx_binding *binding;
-
-  if (SCOPE_FILE_SCOPE_P (scope))
-    scope = global_namespace;
-  else
-    /* Unnecessary for the global namespace because it can't be an alias. */
-    scope = ORIGINAL_NAMESPACE (scope);
-
-  binding = cp_binding_level_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
-
-  return binding ? binding->value : NULL_TREE;
-}
-
 /* Return the binding for NAME in NS.  If NS is NULL, look in
    global_namespace.  */
 
@@ -3993,28 +3950,26 @@ get_namespace_binding (tree ns, tree nam
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   if (!ns)
     ns = global_namespace;
-  tree ret = namespace_binding_1 (ns, name);
+  cxx_binding *binding = find_namespace_binding (ns, name);
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
-  return ret;
+  return binding ? binding->value : NULL_TREE;
 }
 
 static void
 set_namespace_binding (tree scope, tree name, tree val)
 {
-  cxx_binding *b;
-
   if (scope == NULL_TREE)
     scope = global_namespace;
-  b = binding_for_name (NAMESPACE_LEVEL (scope), name);
-  if (!b->value
+  cxx_binding *binding = find_namespace_binding (scope, name, true);
+  if (!binding->value
       /* For templates and using we create a single element OVERLOAD.
 	 Look for the chain to know whether this is really augmenting
 	 an existing overload.  */
       || (TREE_CODE (val) == OVERLOAD && OVL_CHAIN (val))
       || val == error_mark_node)
-    b->value = val;
+    binding->value = val;
   else
-    supplement_binding (b, val);
+    supplement_binding (binding, val);
 }
 
 /* Set value binding og NAME in the global namespace to VAL.  Does not
@@ -4366,7 +4321,7 @@ finish_namespace_using_decl (tree decl,
     return;
 
   cxx_binding *binding
-    = binding_for_name (NAMESPACE_LEVEL (current_namespace), name);
+    = find_namespace_binding (current_namespace, name, true);
 
   tree value = binding->value;
   tree type = binding->type;
@@ -4917,8 +4872,7 @@ unqualified_namespace_lookup_1 (tree nam
   for (; !val; scope = CP_DECL_CONTEXT (scope))
     {
       struct scope_binding binding = EMPTY_SCOPE_BINDING;
-      cxx_binding *b =
-	 cp_binding_level_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+      cxx_binding *b = find_namespace_binding (scope, name);
 
       if (b)
 	ambiguous_decl (&binding, b, flags);
@@ -5021,8 +4975,7 @@ lookup_using_namespace (tree name, struc
     if (TREE_VALUE (iter) == scope)
       {
 	tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
-	cxx_binding *val1 =
-	  cp_binding_level_find_binding_for_name (NAMESPACE_LEVEL (used), name);
+	cxx_binding *val1 = find_namespace_binding (used, name);
 	/* Resolve ambiguities.  */
 	if (val1)
 	  ambiguous_decl (val, val1, flags);
@@ -5092,8 +5045,7 @@ qualified_lookup_using_namespace (tree n
 	    continue;
 	  vec_safe_push (seen_inline, scope);
 
-	  binding =
-	    cp_binding_level_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+	  binding = find_namespace_binding (scope, name);
 	  if (binding)
 	    {
 	      ambiguous_decl (result, binding, flags);
@@ -5610,8 +5562,7 @@ lookup_type_scope_1 (tree name, tag_scop
   /* Look in namespace scope.  */
   if (!val)
     {
-      iter = cp_binding_level_find_binding_for_name
-	       (NAMESPACE_LEVEL (current_decl_namespace ()), name);
+      iter = find_namespace_binding (current_decl_namespace (), name);
 
       if (iter)
 	{
@@ -5668,13 +5619,14 @@ static tree
 lookup_name_innermost_nonclass_level_1 (tree name)
 {
   cp_binding_level *b = innermost_nonclass_level ();
+  cxx_binding *binding = NULL;
 
   if (b->kind == sk_namespace)
-    return namespace_binding_1 (current_namespace, name);
-  else if (cxx_binding *binding = find_local_binding (b, name))
-    return binding->value;
+    binding = find_namespace_binding (current_namespace, name);
   else
-    return NULL_TREE;
+    binding = find_local_binding (b, name);
+
+  return binding ? binding->value : NULL_TREE;
 }
 
 /* Wrapper for lookup_name_innermost_nonclass_level_1.  */

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++ PATCH] namespace bindings
  2017-05-08 15:25     ` Andreas Schwab
@ 2017-05-08 17:03       ` Nathan Sidwell
  0 siblings, 0 replies; 10+ messages in thread
From: Nathan Sidwell @ 2017-05-08 17:03 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 356 bytes --]

On 05/08/2017 11:17 AM, Andreas Schwab wrote:

> g++.dg/cpp0x/defaulted34.C has the same problem.

I'd managed to flub my xcompiler build.  The code path for 
fn-descriptor-using targets is different, and I'd missed that the 
shadowed outer 'fn' was expected to have been initialized  in that case.

Committed the attached fix.

nathan

-- 
Nathan Sidwell

[-- Attachment #2: vtb.diff --]
[-- Type: text/x-patch, Size: 1376 bytes --]

2017-05-08  Nathan Sidwell  <nathan@acm.org>

	* class.c (build_vtbl_initializer): Don't shadow outer variable
	with static var.

Index: cp/class.c
===================================================================
--- cp/class.c	(revision 247746)
+++ cp/class.c	(working copy)
@@ -9769,18 +9769,19 @@ build_vtbl_initializer (tree binfo,
 	  /* Likewise for deleted virtuals.  */
 	  else if (DECL_DELETED_FN (fn_original))
 	    {
-	      static tree fn;
+	      static tree dvirt_fn;
 
-	      if (!fn)
+	      if (!dvirt_fn)
 		{
 		  tree name = get_identifier ("__cxa_deleted_virtual");
-		  fn = IDENTIFIER_GLOBAL_VALUE (name);
-		  if (!fn)
-		    fn = push_library_fn
+		  dvirt_fn = IDENTIFIER_GLOBAL_VALUE (name);
+		  if (!dvirt_fn)
+		    dvirt_fn = push_library_fn
 		      (name,
 		       build_function_type_list (void_type_node, NULL_TREE),
 		       NULL_TREE, ECF_NORETURN);
 		}
+	      fn = dvirt_fn;
 	      if (!TARGET_VTABLE_USES_DESCRIPTORS)
 		init = fold_convert (vfunc_ptr_type_node,
 				     build_fold_addr_expr (fn));
@@ -9789,7 +9790,8 @@ build_vtbl_initializer (tree binfo,
 	    {
 	      if (!integer_zerop (delta) || vcall_index)
 		{
-		  fn = make_thunk (fn, /*this_adjusting=*/1, delta, vcall_index);
+		  fn = make_thunk (fn, /*this_adjusting=*/1,
+				   delta, vcall_index);
 		  if (!DECL_NAME (fn))
 		    finish_thunk (fn);
 		}

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++ PATCH] namespace bindings
  2017-05-08 13:06 ` Jason Merrill via gcc-patches
  2017-05-08 13:34   ` Nathan Sidwell
@ 2017-05-08 15:54   ` Nathan Sidwell
  1 sibling, 0 replies; 10+ messages in thread
From: Nathan Sidwell @ 2017-05-08 15:54 UTC (permalink / raw)
  To: Jason Merrill; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 428 bytes --]

On 05/08/2017 08:56 AM, Jason Merrill wrote:
> On Fri, May 5, 2017 at 4:07 PM, Nathan Sidwell <nathan@acm.org> wrote:
>> This cleanup patch kills IDENTIFIER_NAMESPACE_VALUE and replaces
>> {get,set}_namespace_binding with get_namespace_value and set_global_value
>> respectively.
> 
> I'd prefer to stick with the _binding naming, as "value" is more ambiguous.

I've reverted that bit of the change.

nathan

-- 
Nathan Sidwell

[-- Attachment #2: bin-rev.diff --]
[-- Type: text/x-patch, Size: 7713 bytes --]

2017-05-08  Nathan Sidwell  <nathan@acm.org>

	Revert _binding -> _value change.
	* name-lookup.h (get_namespace_value, set_global_value): Rename to ...
	(get_namespace_binding, set_global_binding): ... these.
	* name-lookup.c (get_namespace_value, set_global_value): Rename to ...
	(get_namespace_binding, set_global_binding): ... these.
	(arg_assoc_namespace, pushdecl_maybe_friend_1,
	check_for_out_of_scope_variable, push_overloaded_decl_1,
	lookup_name_innermost_nonclass_level, push_namespace): Adjust.
	* cp-tree.h (IDENTIFIER_GLOBAL_VALUE,
	SET_IDENTIFIER_GLOBAL_VALUE): Adjust.
	* decl.c (poplevel): Adjust.
	* pt.c (make_constrained_auto): Likewise.

Index: cp-tree.h
===================================================================
--- cp-tree.h	(revision 247739)
+++ cp-tree.h	(working copy)
@@ -554,9 +554,9 @@ struct GTY(()) ptrmem_cst {
 typedef struct ptrmem_cst * ptrmem_cst_t;
 
 #define IDENTIFIER_GLOBAL_VALUE(NODE) \
-  get_namespace_value (NULL_TREE, (NODE))
+  get_namespace_binding (NULL_TREE, (NODE))
 #define SET_IDENTIFIER_GLOBAL_VALUE(NODE, VAL) \
-  set_global_value ((NODE), (VAL))
+  set_global_binding ((NODE), (VAL))
 
 #define CLEANUP_P(NODE)		TREE_LANG_FLAG_0 (TRY_BLOCK_CHECK (NODE))
 
Index: decl.c
===================================================================
--- decl.c	(revision 247739)
+++ decl.c	(working copy)
@@ -693,7 +693,7 @@ poplevel (int keep, int reverse, int fun
 					   /*class_p=*/true);
 	  tree ns_binding = NULL_TREE;
 	  if (!ob)
-	    ns_binding = get_namespace_value (current_namespace, name);
+	    ns_binding = get_namespace_binding (current_namespace, name);
 
 	  if (ob && ob->scope == current_binding_level->level_chain)
 	    /* We have something like:
Index: name-lookup.c
===================================================================
--- name-lookup.c	(revision 247739)
+++ name-lookup.c	(working copy)
@@ -215,7 +215,7 @@ arg_assoc_namespace (struct arg_lookup *
       if (arg_assoc_namespace (k, TREE_PURPOSE (value)))
 	return true;
 
-  value = get_namespace_value (scope, k->name);
+  value = get_namespace_binding (scope, k->name);
   if (!value)
     return false;
 
@@ -1250,7 +1250,7 @@ pushdecl_maybe_friend_1 (tree x, bool is
       /* In case this decl was explicitly namespace-qualified, look it
 	 up in its namespace context.  */
       if (DECL_NAMESPACE_SCOPE_P (x) && namespace_bindings_p ())
-	t = get_namespace_value (DECL_CONTEXT (x), name);
+	t = get_namespace_binding (DECL_CONTEXT (x), name);
       else
 	t = lookup_name_innermost_nonclass_level (name);
 
@@ -1267,7 +1267,7 @@ pushdecl_maybe_friend_1 (tree x, bool is
 	  t = innermost_non_namespace_value (name);
 	  /* Or in the innermost namespace.  */
 	  if (! t)
-	    t = get_namespace_value (DECL_CONTEXT (x), name);
+	    t = get_namespace_binding (DECL_CONTEXT (x), name);
 	  /* Does it have linkage?  Note that if this isn't a DECL, it's an
 	     OVERLOAD, which is OK.  */
 	  if (t && DECL_P (t) && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
@@ -1521,7 +1521,7 @@ pushdecl_maybe_friend_1 (tree x, bool is
 	{
 	  tree decl;
 
-	  decl = get_namespace_value (current_namespace, name);
+	  decl = get_namespace_binding (current_namespace, name);
 	  if (decl && TREE_CODE (decl) == OVERLOAD)
 	    decl = OVL_FUNCTION (decl);
 
@@ -1568,7 +1568,7 @@ pushdecl_maybe_friend_1 (tree x, bool is
       else
 	{
 	  /* Here to install a non-global value.  */
-	  tree oldglobal = get_namespace_value (current_namespace, name);
+	  tree oldglobal = get_namespace_binding (current_namespace, name);
 	  tree oldlocal = NULL_TREE;
 	  cp_binding_level *oldscope = NULL;
 	  cxx_binding *oldbinding = outer_binding (name, NULL, true);
@@ -1608,7 +1608,7 @@ pushdecl_maybe_friend_1 (tree x, bool is
 
 	      if (oldlocal == NULL_TREE)
 		oldlocal
-		  = get_namespace_value (current_namespace, DECL_NAME (d));
+		  = get_namespace_binding (current_namespace, DECL_NAME (d));
 	    }
 
 	  /* If this is an extern function declaration, see if we
@@ -1972,7 +1972,7 @@ check_for_out_of_scope_variable (tree de
     shadowed = DECL_HAS_SHADOWED_FOR_VAR_P (shadowed)
       ? DECL_SHADOWED_FOR_VAR (shadowed) : NULL_TREE;
   if (!shadowed)
-    shadowed = get_namespace_value (current_namespace, DECL_NAME (decl));
+    shadowed = get_namespace_binding (current_namespace, DECL_NAME (decl));
   if (shadowed)
     {
       if (!DECL_ERROR_REPORTED (decl))
@@ -2934,7 +2934,7 @@ push_overloaded_decl_1 (tree decl, int f
   int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL));
 
   if (doing_global)
-    old = get_namespace_value (DECL_CONTEXT (decl), name);
+    old = get_namespace_binding (DECL_CONTEXT (decl), name);
   else
     old = lookup_name_innermost_nonclass_level (name);
 
@@ -4023,7 +4023,7 @@ namespace_binding_1 (tree name, tree sco
    global_namespace.  */
 
 tree
-get_namespace_value (tree ns, tree name)
+get_namespace_binding (tree ns, tree name)
 {
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   if (!ns)
@@ -4052,11 +4052,11 @@ set_namespace_binding (tree name, tree s
     supplement_binding (b, val);
 }
 
-/* Set NAME in the global namespace to VAL.  Does not add it to the
-   list of things in the namespace.  */
+/* Set value binding og NAME in the global namespace to VAL.  Does not
+   add it to the list of things in the namespace.  */
 
 void
-set_global_value (tree name, tree val)
+set_global_binding (tree name, tree val)
 {
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
 
@@ -5823,7 +5823,7 @@ lookup_name_innermost_nonclass_level_1 (
 
   if (b->kind == sk_namespace)
     {
-      t = get_namespace_value (current_namespace, name);
+      t = get_namespace_binding (current_namespace, name);
 
       /* extern "C" function() */
       if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST)
@@ -6475,7 +6475,7 @@ push_namespace (tree name)
   if (anon)
     {
       name = anon_identifier;
-      d = get_namespace_value (current_namespace, name);
+      d = get_namespace_binding (current_namespace, name);
       if (d)
 	/* Reopening anonymous namespace.  */
 	need_new = false;
@@ -6484,7 +6484,7 @@ push_namespace (tree name)
   else
     {
       /* Check whether this is an extended namespace definition.  */
-      d = get_namespace_value (current_namespace, name);
+      d = get_namespace_binding (current_namespace, name);
       if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)
 	{
 	  tree dna = DECL_NAMESPACE_ALIAS (d);
Index: name-lookup.h
===================================================================
--- name-lookup.h	(revision 247739)
+++ name-lookup.h	(working copy)
@@ -311,8 +311,8 @@ extern tree pushdecl_with_scope (tree, c
 extern tree lookup_name_prefer_type (tree, int);
 extern tree lookup_name_real (tree, int, int, bool, int, int);
 extern tree lookup_type_scope (tree, tag_scope);
-extern tree get_namespace_value (tree ns, tree id);
-extern void set_global_value (tree id, tree val);
+extern tree get_namespace_binding (tree ns, tree id);
+extern void set_global_binding (tree id, tree val);
 extern bool hidden_name_p (tree);
 extern tree remove_hidden_names (tree);
 extern tree lookup_qualified_name (tree, tree, int, bool, /*hidden*/bool = false);
Index: pt.c
===================================================================
--- pt.c	(revision 247739)
+++ pt.c	(working copy)
@@ -24731,7 +24731,7 @@ make_constrained_auto (tree con, tree ar
 static tree
 listify (tree arg)
 {
-  tree std_init_list = get_namespace_value (std_node, init_list_identifier);
+  tree std_init_list = get_namespace_binding (std_node, init_list_identifier);
   tree argvec;
   if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list))
     {    

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++ PATCH] namespace bindings
  2017-05-08 14:33   ` Nathan Sidwell
@ 2017-05-08 15:25     ` Andreas Schwab
  2017-05-08 17:03       ` Nathan Sidwell
  0 siblings, 1 reply; 10+ messages in thread
From: Andreas Schwab @ 2017-05-08 15:25 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches

On Mai 08 2017, Nathan Sidwell <nathan@acm.org> wrote:

> On 05/08/2017 08:07 AM, Andreas Schwab wrote:
>> On Mai 05 2017, Nathan Sidwell <nathan@acm.org> wrote:
>>
>>> This cleanup patch kills IDENTIFIER_NAMESPACE_VALUE and replaces
>>> {get,set}_namespace_binding with get_namespace_value and set_global_value
>>> respectively.
>>
>> I'm getting this regression on ia64:
>>
>> FAIL: g++.dg/template/virtual3.C  -std=c++11 (test for excess errors)
>
> I'm not seeing this.  On an ia64-linux target (hosted on x86_64-linux) I
> get the attached output, which is the same as I get on an x86_64-linux
> native build.

g++.dg/cpp0x/defaulted34.C has the same problem.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++ PATCH] namespace bindings
  2017-05-08 12:41 ` Andreas Schwab
  2017-05-08 13:14   ` Nathan Sidwell
@ 2017-05-08 14:33   ` Nathan Sidwell
  2017-05-08 15:25     ` Andreas Schwab
  1 sibling, 1 reply; 10+ messages in thread
From: Nathan Sidwell @ 2017-05-08 14:33 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 718 bytes --]

On 05/08/2017 08:07 AM, Andreas Schwab wrote:
> On Mai 05 2017, Nathan Sidwell <nathan@acm.org> wrote:
> 
>> This cleanup patch kills IDENTIFIER_NAMESPACE_VALUE and replaces
>> {get,set}_namespace_binding with get_namespace_value and set_global_value
>> respectively.
> 
> I'm getting this regression on ia64:
> 
> FAIL: g++.dg/template/virtual3.C  -std=c++11 (test for excess errors)

I'm not seeing this.  On an ia64-linux target (hosted on x86_64-linux) I 
get the attached output, which is the same as I get on an x86_64-linux 
native build.

For the failure mode you describe I'd expect many more test failures to 
occur.  I wonder if there's some uninitialized variable or something?

nathan

-- 
Nathan Sidwell

[-- Attachment #2: virt.out --]
[-- Type: text/plain, Size: 1881 bytes --]

virtual3.C:8:8: error: deleted function 'virtual B::~B()'
 struct B : A<0>, A<1>  // { dg-error "deleted|context" }
        ^
virtual3.C:5:11: error: overriding non-deleted function 'A<<anonymous> >::~A() [with int <anonymous> = 0]'
   virtual ~A();   // { dg-message "non-deleted|private" }
           ^
virtual3.C:8:8: note: 'virtual B::~B()' is implicitly deleted because the default definition would be ill-formed:
 struct B : A<0>, A<1>  // { dg-error "deleted|context" }
        ^
virtual3.C:8:8: error: 'A<<anonymous> >::~A() [with int <anonymous> = 0]' is private within this context
virtual3.C:5:11: note: declared private here
   virtual ~A();   // { dg-message "non-deleted|private" }
           ^
virtual3.C:8:8: error: 'A<<anonymous> >::~A() [with int <anonymous> = 1]' is private within this context
 struct B : A<0>, A<1>  // { dg-error "deleted|context" }
        ^
virtual3.C:5:11: note: declared private here
   virtual ~A();   // { dg-message "non-deleted|private" }
           ^
virtual3.C:8:8: error: deleted function 'virtual B::~B()'
 struct B : A<0>, A<1>  // { dg-error "deleted|context" }
        ^
virtual3.C:5:11: error: overriding non-deleted function 'A<<anonymous> >::~A() [with int <anonymous> = 1]'
   virtual ~A();   // { dg-message "non-deleted|private" }
           ^
virtual3.C: In constructor 'B::B()':
virtual3.C:10:7: error: 'A<<anonymous> >::~A() [with int <anonymous> = 0]' is private within this context
   B() {}   // { dg-error "context" }
       ^
virtual3.C:5:11: note: declared private here
   virtual ~A();   // { dg-message "non-deleted|private" }
           ^
virtual3.C:10:7: error: 'A<<anonymous> >::~A() [with int <anonymous> = 1]' is private within this context
   B() {}   // { dg-error "context" }
       ^
virtual3.C:5:11: note: declared private here
   virtual ~A();   // { dg-message "non-deleted|private" }
           ^

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++ PATCH] namespace bindings
  2017-05-08 13:06 ` Jason Merrill via gcc-patches
@ 2017-05-08 13:34   ` Nathan Sidwell
  2017-05-08 15:54   ` Nathan Sidwell
  1 sibling, 0 replies; 10+ messages in thread
From: Nathan Sidwell @ 2017-05-08 13:34 UTC (permalink / raw)
  To: Jason Merrill; +Cc: GCC Patches

On 05/08/2017 08:56 AM, Jason Merrill wrote:
> On Fri, May 5, 2017 at 4:07 PM, Nathan Sidwell <nathan@acm.org> wrote:
>> This cleanup patch kills IDENTIFIER_NAMESPACE_VALUE and replaces
>> {get,set}_namespace_binding with get_namespace_value and set_global_value
>> respectively.
> 
> I'd prefer to stick with the _binding naming, as "value" is more ambiguous.

Ok.  It is getting the 'value' binding, ignoring the 'type' binding, fwiw.

nathan

-- 
Nathan Sidwell

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++ PATCH] namespace bindings
  2017-05-08 12:41 ` Andreas Schwab
@ 2017-05-08 13:14   ` Nathan Sidwell
  2017-05-08 14:33   ` Nathan Sidwell
  1 sibling, 0 replies; 10+ messages in thread
From: Nathan Sidwell @ 2017-05-08 13:14 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: GCC Patches

On 05/08/2017 08:07 AM, Andreas Schwab wrote:
> On Mai 05 2017, Nathan Sidwell <nathan@acm.org> wrote:
> 
>> This cleanup patch kills IDENTIFIER_NAMESPACE_VALUE and replaces
>> {get,set}_namespace_binding with get_namespace_value and set_global_value
>> respectively.
> 
> I'm getting this regression on ia64:


Sorry, I'll take a look ...


-- 
Nathan Sidwell

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++ PATCH] namespace bindings
  2017-05-05 20:25 Nathan Sidwell
  2017-05-08 12:41 ` Andreas Schwab
@ 2017-05-08 13:06 ` Jason Merrill via gcc-patches
  2017-05-08 13:34   ` Nathan Sidwell
  2017-05-08 15:54   ` Nathan Sidwell
  1 sibling, 2 replies; 10+ messages in thread
From: Jason Merrill via gcc-patches @ 2017-05-08 13:06 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches

On Fri, May 5, 2017 at 4:07 PM, Nathan Sidwell <nathan@acm.org> wrote:
> This cleanup patch kills IDENTIFIER_NAMESPACE_VALUE and replaces
> {get,set}_namespace_binding with get_namespace_value and set_global_value
> respectively.

I'd prefer to stick with the _binding naming, as "value" is more ambiguous.

Jason

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++ PATCH] namespace bindings
  2017-05-05 20:25 Nathan Sidwell
@ 2017-05-08 12:41 ` Andreas Schwab
  2017-05-08 13:14   ` Nathan Sidwell
  2017-05-08 14:33   ` Nathan Sidwell
  2017-05-08 13:06 ` Jason Merrill via gcc-patches
  1 sibling, 2 replies; 10+ messages in thread
From: Andreas Schwab @ 2017-05-08 12:41 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: GCC Patches

On Mai 05 2017, Nathan Sidwell <nathan@acm.org> wrote:

> This cleanup patch kills IDENTIFIER_NAMESPACE_VALUE and replaces
> {get,set}_namespace_binding with get_namespace_value and set_global_value
> respectively.

I'm getting this regression on ia64:

FAIL: g++.dg/template/virtual3.C  -std=c++11 (test for excess errors)
Excess errors:
/usr/local/gcc/gcc-20170508/gcc/testsuite/g++.dg/template/virtual3.C:11:2: error: use of deleted function 'virtual B::~B()'
/usr/local/gcc/gcc-20170508/gcc/testsuite/g++.dg/template/virtual3.C:11:2: error: use of deleted function 'virtual B::~B()'
/usr/local/gcc/gcc-20170508/gcc/testsuite/g++.dg/template/virtual3.C:11:2: error: use of deleted function 'virtual B::~B()'
/usr/local/gcc/gcc-20170508/gcc/testsuite/g++.dg/template/virtual3.C:11:2: error: use of deleted function 'virtual B::~B()'
/usr/local/gcc/gcc-20170508/gcc/testsuite/g++.dg/template/virtual3.C:11:2: error: use of deleted function 'virtual B::~B()'
/usr/local/gcc/gcc-20170508/gcc/testsuite/g++.dg/template/virtual3.C:11:2: error: use of deleted function 'virtual B::~B()'
/usr/local/gcc/gcc-20170508/gcc/testsuite/g++.dg/template/virtual3.C:11:2: error: use of deleted function 'virtual B::~B()'
/usr/local/gcc/gcc-20170508/gcc/testsuite/g++.dg/template/virtual3.C:11:2: error: use of deleted function 'virtual B::~B()'

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [C++ PATCH] namespace bindings
@ 2017-05-05 20:25 Nathan Sidwell
  2017-05-08 12:41 ` Andreas Schwab
  2017-05-08 13:06 ` Jason Merrill via gcc-patches
  0 siblings, 2 replies; 10+ messages in thread
From: Nathan Sidwell @ 2017-05-05 20:25 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 416 bytes --]

This cleanup patch kills IDENTIFIER_NAMESPACE_VALUE and replaces 
{get,set}_namespace_binding with get_namespace_value and 
set_global_value respectively.

we're a little confused as to whether 'toplevel' means any namespace or 
means the global namespace.  I'm trying to be consistent such that 
global means :: and namespace means namespace and toplevel isn't used.

Committed to trunk.

nathan
-- 
Nathan Sidwell

[-- Attachment #2: bin.diff --]
[-- Type: text/x-patch, Size: 25648 bytes --]

2017-05-05  Nathan Sidwell  <nathan@acm.org>

	* cp-tree.h (IDENTIFIER_GLOBAL_VALUE): Use get_namespace_value.
	(SET_IDENTIFIER_GLOBAL_VALUE): Use set_global_value.
	(IDENTIFIER_NAMESPACE_VALUE): Delete.
	* name-lookup.h (namespace_binding, set_namespace_binding): Replace
	with ...
	(get_namespace_value, set_global_value): ... these.
	(get_global_value_if_present, is_typename_at_global_scope): Delete.
	* decl.c (poplevel): Use get_namespace_value.
	(grokdeclarator): Use IDENTIFIER_GLOBAL_VALUE.
	* class.c (build_vtbl_initializer): Stash library decl in
	static var. Use IDENTIFIER_GLOBAL_VALUE.
	* except.c (do_get_exception_ptr, do_begin_catch, do_end_catch,
	do_allocate_exception, do_free_exception, build_throw): Likewise.
	* init.c (throw_bad_array_new_length): Likewise.
	* rtti.c (throw_bad_cast, throw_bad_typeid): Likewise.
	* name-lookup.c (arg_assoc_namespace, pushdecl_maybe_friend_1,
	check_for_our_of_scope_variable, push_overloaded_decl_1): Use
	get_namespace_value.
	(set_namespace_binding_1): Rename to
	(set_namespace_binding): ... here.
	(set_global_value): New.
	(lookup_name_innermost_nonclass_level_1, push_namespace): Use
	get_namespace_value.
	* pt.c (listify): Use get_namespace_value.

Index: class.c
===================================================================
--- class.c	(revision 247647)
+++ class.c	(working copy)
@@ -9769,11 +9769,18 @@ build_vtbl_initializer (tree binfo,
 	  /* Likewise for deleted virtuals.  */
 	  else if (DECL_DELETED_FN (fn_original))
 	    {
-	      fn = get_identifier ("__cxa_deleted_virtual");
-	      if (!get_global_value_if_present (fn, &fn))
-		fn = push_library_fn (fn, (build_function_type_list
-					   (void_type_node, NULL_TREE)),
-				      NULL_TREE, ECF_NORETURN);
+	      static tree fn;
+
+	      if (!fn)
+		{
+		  tree name = get_identifier ("__cxa_deleted_virtual");
+		  fn = IDENTIFIER_GLOBAL_VALUE (name);
+		  if (!fn)
+		    fn = push_library_fn
+		      (name,
+		       build_function_type_list (void_type_node, NULL_TREE),
+		       NULL_TREE, ECF_NORETURN);
+		}
 	      if (!TARGET_VTABLE_USES_DESCRIPTORS)
 		init = fold_convert (vfunc_ptr_type_node,
 				     build_fold_addr_expr (fn));
Index: cp-tree.h
===================================================================
--- cp-tree.h	(revision 247647)
+++ cp-tree.h	(working copy)
@@ -554,13 +554,9 @@ struct GTY(()) ptrmem_cst {
 typedef struct ptrmem_cst * ptrmem_cst_t;
 
 #define IDENTIFIER_GLOBAL_VALUE(NODE) \
-  namespace_binding ((NODE), global_namespace)
+  get_namespace_value (NULL_TREE, (NODE))
 #define SET_IDENTIFIER_GLOBAL_VALUE(NODE, VAL) \
-  set_namespace_binding ((NODE), global_namespace, (VAL))
-#define IDENTIFIER_NAMESPACE_VALUE(NODE) \
-  namespace_binding ((NODE), current_namespace)
-#define SET_IDENTIFIER_NAMESPACE_VALUE(NODE, VAL) \
-  set_namespace_binding ((NODE), current_namespace, (VAL))
+  set_global_value ((NODE), (VAL))
 
 #define CLEANUP_P(NODE)		TREE_LANG_FLAG_0 (TRY_BLOCK_CHECK (NODE))
 
Index: decl.c
===================================================================
--- decl.c	(revision 247647)
+++ decl.c	(working copy)
@@ -687,16 +687,13 @@ poplevel (int keep, int reverse, int fun
 	  && DECL_NAME (link))
 	{
 	  tree name = DECL_NAME (link);
-	  cxx_binding *ob;
-	  tree ns_binding;
 
-	  ob = outer_binding (name,
-			      IDENTIFIER_BINDING (name),
-			      /*class_p=*/true);
+	  cxx_binding *ob = outer_binding (name,
+					   IDENTIFIER_BINDING (name),
+					   /*class_p=*/true);
+	  tree ns_binding = NULL_TREE;
 	  if (!ob)
-	    ns_binding = IDENTIFIER_NAMESPACE_VALUE (name);
-	  else
-	    ns_binding = NULL_TREE;
+	    ns_binding = get_namespace_value (current_namespace, name);
 
 	  if (ob && ob->scope == current_binding_level->level_chain)
 	    /* We have something like:
@@ -10148,7 +10145,8 @@ grokdeclarator (const cp_declarator *dec
 		    gcc_assert (flags == NO_SPECIAL);
 		    flags = TYPENAME_FLAG;
 		    sfk = sfk_conversion;
-		    if (is_typename_at_global_scope (dname))
+		    tree glob = IDENTIFIER_GLOBAL_VALUE (dname);
+		    if (glob && TREE_CODE (glob) == TYPE_DECL)
 		      name = identifier_to_locale (IDENTIFIER_POINTER (dname));
 		    else
 		      name = "<invalid operator>";
Index: except.c
===================================================================
--- except.c	(revision 247647)
+++ except.c	(working copy)
@@ -154,14 +154,17 @@ declare_library_fn (tree name, tree retu
 static tree
 do_get_exception_ptr (void)
 {
-  tree fn;
+  static tree fn;
 
-  fn = get_identifier ("__cxa_get_exception_ptr");
-  if (!get_global_value_if_present (fn, &fn))
+  if (!fn)
     {
-      /* Declare void* __cxa_get_exception_ptr (void *) throw().  */
-      fn = declare_library_fn (fn, ptr_type_node, ptr_type_node,
-			       ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE);
+      tree name = get_identifier ("__cxa_get_exception_ptr");
+      fn = IDENTIFIER_GLOBAL_VALUE (name);
+      if (!fn)
+	/* Declare void* __cxa_get_exception_ptr (void *) throw().  */
+	fn = declare_library_fn
+	  (name, ptr_type_node, ptr_type_node,
+	   ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE);
     }
 
   return cp_build_function_call_nary (fn, tf_warning_or_error,
@@ -174,22 +177,29 @@ do_get_exception_ptr (void)
 static tree
 do_begin_catch (void)
 {
-  tree fn;
+  static tree fn;
 
-  fn = get_identifier ("__cxa_begin_catch");
-  if (!get_global_value_if_present (fn, &fn))
+  if (!fn)
     {
-      /* Declare void* __cxa_begin_catch (void *) throw().  */
-      fn = declare_library_fn (fn, ptr_type_node, ptr_type_node, ECF_NOTHROW);
+      tree name = fn = get_identifier ("__cxa_begin_catch");
+      fn = IDENTIFIER_GLOBAL_VALUE (name);
+      if (!fn)
+	{
+	  /* Declare void* __cxa_begin_catch (void *) throw().  */
+	  fn = declare_library_fn
+	    (name, ptr_type_node, ptr_type_node, ECF_NOTHROW);
 
-      /* Create its transactional-memory equivalent.  */
-      if (flag_tm)
-	{
-	  tree fn2 = get_identifier ("_ITM_cxa_begin_catch");
-	  if (!get_global_value_if_present (fn2, &fn2))
-	    fn2 = declare_library_fn (fn2, ptr_type_node,
-				      ptr_type_node, ECF_NOTHROW | ECF_TM_PURE);
-	  record_tm_replacement (fn, fn2);
+	  /* Create its transactional-memory equivalent.  */
+	  if (flag_tm)
+	    {
+	      tree itm_name = get_identifier ("_ITM_cxa_begin_catch");
+	      tree itm_fn = IDENTIFIER_GLOBAL_VALUE (itm_name);
+	      if (!itm_fn)
+		itm_fn = declare_library_fn
+		  (itm_name, ptr_type_node, ptr_type_node,
+		   ECF_NOTHROW | ECF_TM_PURE);
+	      record_tm_replacement (fn, itm_fn);
+	    }
 	}
     }
 
@@ -221,26 +231,32 @@ dtor_nothrow (tree type)
 static tree
 do_end_catch (tree type)
 {
-  tree fn, cleanup;
+  static tree fn;
 
-  fn = get_identifier ("__cxa_end_catch");
-  if (!get_global_value_if_present (fn, &fn))
+  if (!fn)
     {
-      /* Declare void __cxa_end_catch ().
-         This can throw if the destructor for the exception throws.  */
-      fn = push_void_library_fn (fn, void_list_node, 0);
-
-      /* Create its transactional-memory equivalent.  */
-      if (flag_tm)
+      tree name = get_identifier ("__cxa_end_catch");
+      fn = IDENTIFIER_GLOBAL_VALUE (name);
+      if (!fn)
 	{
-	  tree fn2 = get_identifier ("_ITM_cxa_end_catch");
-	  if (!get_global_value_if_present (fn2, &fn2))
-	    fn2 = push_void_library_fn (fn2, void_list_node, ECF_TM_PURE);
-	  record_tm_replacement (fn, fn2);
+	  /* Declare void __cxa_end_catch ().
+	     This can throw if the destructor for the exception throws.  */
+	  fn = push_void_library_fn (name, void_list_node, 0);
+
+	  /* Create its transactional-memory equivalent.  */
+	  if (flag_tm)
+	    {
+	      tree itm_name = get_identifier ("_ITM_cxa_end_catch");
+	      tree itm_fn = IDENTIFIER_GLOBAL_VALUE (itm_name);
+	      if (!itm_fn)
+		itm_fn = push_void_library_fn
+		  (itm_name, void_list_node, ECF_TM_PURE);
+	      record_tm_replacement (fn, itm_fn);
+	    }
 	}
     }
 
-  cleanup = cp_build_function_call_vec (fn, NULL, tf_warning_or_error);
+  tree cleanup = cp_build_function_call_vec (fn, NULL, tf_warning_or_error);
   TREE_NOTHROW (cleanup) = dtor_nothrow (type);
 
   return cleanup;
@@ -500,23 +516,28 @@ finish_eh_spec_block (tree raw_raises, t
 static tree
 do_allocate_exception (tree type)
 {
-  tree fn;
+  static tree fn;
 
-  fn = get_identifier ("__cxa_allocate_exception");
-  if (!get_global_value_if_present (fn, &fn))
+  if (!fn)
     {
-      /* Declare void *__cxa_allocate_exception(size_t) throw().  */
-      fn = declare_library_fn (fn, ptr_type_node, size_type_node,
-			        ECF_NOTHROW | ECF_MALLOC);
-
-      if (flag_tm)
-	{
-	  tree fn2 = get_identifier ("_ITM_cxa_allocate_exception");
-	  if (!get_global_value_if_present (fn2, &fn2))
-	    fn2 = declare_library_fn (fn2, ptr_type_node,
-				      size_type_node, 
-				      ECF_NOTHROW | ECF_MALLOC | ECF_TM_PURE);
-	  record_tm_replacement (fn, fn2);
+      tree name = get_identifier ("__cxa_allocate_exception");
+      fn = IDENTIFIER_GLOBAL_VALUE (name);
+      if (!fn)
+	{
+	  /* Declare void *__cxa_allocate_exception(size_t) throw().  */
+	  fn = declare_library_fn (name, ptr_type_node, size_type_node,
+				   ECF_NOTHROW | ECF_MALLOC);
+
+	  if (flag_tm)
+	    {
+	      tree itm_name = get_identifier ("_ITM_cxa_allocate_exception");
+	      tree itm_fn = IDENTIFIER_GLOBAL_VALUE (itm_name);
+	      if (!itm_fn)
+		itm_fn = declare_library_fn
+		  (itm_name, ptr_type_node, size_type_node, 
+		   ECF_NOTHROW | ECF_MALLOC | ECF_TM_PURE);
+	      record_tm_replacement (fn, itm_fn);
+	    }
 	}
     }
 
@@ -530,23 +551,28 @@ do_allocate_exception (tree type)
 static tree
 do_free_exception (tree ptr)
 {
-  tree fn;
+  static tree fn;
 
-  fn = get_identifier ("__cxa_free_exception");
-  if (!get_global_value_if_present (fn, &fn))
+  if (!fn)
     {
-      /* Declare void __cxa_free_exception (void *) throw().  */
-      fn = declare_library_fn (fn, void_type_node, ptr_type_node,
-			       ECF_NOTHROW | ECF_LEAF);
-
-      if (flag_tm)
-	{
-	  tree fn2 = get_identifier ("_ITM_cxa_free_exception");
-	  if (!get_global_value_if_present (fn2, &fn2))
-	    fn2 = declare_library_fn (fn2, void_type_node,
-				      ptr_type_node,
-				      ECF_NOTHROW | ECF_LEAF | ECF_TM_PURE);
-	  record_tm_replacement (fn, fn2);
+      tree name = get_identifier ("__cxa_free_exception");
+      fn = IDENTIFIER_GLOBAL_VALUE (name);
+      if (!fn)
+	{
+	  /* Declare void __cxa_free_exception (void *) throw().  */
+	  fn = declare_library_fn (name, void_type_node, ptr_type_node,
+				   ECF_NOTHROW | ECF_LEAF);
+
+	  if (flag_tm)
+	    {
+	      tree itm_name = get_identifier ("_ITM_cxa_free_exception");
+	      tree itm_fn = IDENTIFIER_GLOBAL_VALUE (itm_name);
+	      if (!itm_fn)
+		itm_fn = declare_library_fn
+		  (itm_name, void_type_node, ptr_type_node,
+		   ECF_NOTHROW | ECF_LEAF | ECF_TM_PURE);
+	      record_tm_replacement (fn, itm_fn);
+	    }
 	}
     }
 
@@ -588,8 +614,6 @@ wrap_cleanups_r (tree *tp, int *walk_sub
 tree
 build_throw (tree exp)
 {
-  tree fn;
-
   if (exp == error_mark_node)
     return exp;
 
@@ -616,6 +640,7 @@ build_throw (tree exp)
 
   if (exp)
     {
+      static tree throw_fn;
       tree throw_type;
       tree temp_type;
       tree cleanup;
@@ -631,23 +656,28 @@ build_throw (tree exp)
 	  cleanup_type = build_pointer_type (tmp);
 	}
 
-      fn = get_identifier ("__cxa_throw");
-      if (!get_global_value_if_present (fn, &fn))
+      if (!throw_fn)
 	{
-	  /* Declare void __cxa_throw (void*, void*, void (*)(void*)).  */
-	  /* ??? Second argument is supposed to be "std::type_info*".  */
-	  tmp = build_function_type_list (void_type_node,
-					  ptr_type_node, ptr_type_node,
-					  cleanup_type, NULL_TREE);
-	  fn = push_throw_library_fn (fn, tmp);
-
-	  if (flag_tm)
+	  tree name = get_identifier ("__cxa_throw");
+	  throw_fn = IDENTIFIER_GLOBAL_VALUE (name);
+	  if (!throw_fn)
 	    {
-	      tree fn2 = get_identifier ("_ITM_cxa_throw");
-	      if (!get_global_value_if_present (fn2, &fn2))
-		fn2 = push_throw_library_fn (fn2, tmp);
-	      apply_tm_attr (fn2, get_identifier ("transaction_pure"));
-	      record_tm_replacement (fn, fn2);
+	      /* Declare void __cxa_throw (void*, void*, void (*)(void*)).  */
+	      /* ??? Second argument is supposed to be "std::type_info*".  */
+	      tmp = build_function_type_list (void_type_node,
+					      ptr_type_node, ptr_type_node,
+					      cleanup_type, NULL_TREE);
+	      throw_fn = push_throw_library_fn (name, tmp);
+
+	      if (flag_tm)
+		{
+		  tree itm_name = get_identifier ("_ITM_cxa_throw");
+		  tree itm_fn = IDENTIFIER_GLOBAL_VALUE (itm_name);
+		  if (!itm_fn)
+		    itm_fn = push_throw_library_fn (itm_name, tmp);
+		  apply_tm_attr (itm_fn, get_identifier ("transaction_pure"));
+		  record_tm_replacement (throw_fn, itm_fn);
+		}
 	    }
 	}
 
@@ -739,22 +769,22 @@ build_throw (tree exp)
       cleanup = NULL_TREE;
       if (type_build_dtor_call (TREE_TYPE (object)))
 	{
-	  tree fn = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
-				     complete_dtor_identifier, 0);
-	  fn = BASELINK_FUNCTIONS (fn);
-	  mark_used (fn);
+	  tree dtor_fn = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
+					  complete_dtor_identifier, 0);
+	  dtor_fn = BASELINK_FUNCTIONS (dtor_fn);
+	  mark_used (dtor_fn);
 	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object)))
 	    {
-	      cxx_mark_addressable (fn);
+	      cxx_mark_addressable (dtor_fn);
 	      /* Pretend it's a normal function.  */
-	      cleanup = build1 (ADDR_EXPR, cleanup_type, fn);
+	      cleanup = build1 (ADDR_EXPR, cleanup_type, dtor_fn);
 	    }
 	}
       if (cleanup == NULL_TREE)
 	cleanup = build_int_cst (cleanup_type, 0);
 
       /* ??? Indicate that this function call throws throw_type.  */
-      tmp = cp_build_function_call_nary (fn, tf_warning_or_error,
+      tmp = cp_build_function_call_nary (throw_fn, tf_warning_or_error,
 					 ptr, throw_type, cleanup, NULL_TREE);
 
       /* Tack on the initialization stuff.  */
@@ -763,21 +793,24 @@ build_throw (tree exp)
   else
     {
       /* Rethrow current exception.  */
+      static tree rethrow_fn;
 
-      tree fn = get_identifier ("__cxa_rethrow");
-      if (!get_global_value_if_present (fn, &fn))
+      if (!rethrow_fn)
 	{
-	  /* Declare void __cxa_rethrow (void).  */
-	  fn = push_throw_library_fn
-	    (fn, build_function_type_list (void_type_node, NULL_TREE));
-	}
+	  tree name = get_identifier ("__cxa_rethrow");
+	  rethrow_fn = IDENTIFIER_GLOBAL_VALUE (name);
+	  if (!rethrow_fn)
+	    /* Declare void __cxa_rethrow (void).  */
+	    rethrow_fn = push_throw_library_fn
+	      (name, build_function_type_list (void_type_node, NULL_TREE));
 
-      if (flag_tm)
-	apply_tm_attr (fn, get_identifier ("transaction_pure"));
+	  if (flag_tm)
+	    apply_tm_attr (rethrow_fn, get_identifier ("transaction_pure"));
+	}
 
       /* ??? Indicate that this function call allows exceptions of the type
 	 of the enclosing catch block (if known).  */
-      exp = cp_build_function_call_vec (fn, NULL, tf_warning_or_error);
+      exp = cp_build_function_call_vec (rethrow_fn, NULL, tf_warning_or_error);
     }
 
   exp = build1 (THROW_EXPR, void_type_node, exp);
Index: init.c
===================================================================
--- init.c	(revision 247647)
+++ init.c	(working copy)
@@ -2402,10 +2402,16 @@ diagnose_uninitialized_cst_or_ref_member
 tree
 throw_bad_array_new_length (void)
 {
-  tree fn = get_identifier ("__cxa_throw_bad_array_new_length");
-  if (!get_global_value_if_present (fn, &fn))
-    fn = push_throw_library_fn (fn, build_function_type_list (sizetype,
-							      NULL_TREE));
+  static tree fn;
+  if (!fn)
+    {
+      tree name = get_identifier ("__cxa_throw_bad_array_new_length");
+
+      fn = IDENTIFIER_GLOBAL_VALUE (name);
+      if (!fn)
+	fn = push_throw_library_fn
+	  (name, build_function_type_list (sizetype, NULL_TREE));
+    }
 
   return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
 }
Index: name-lookup.c
===================================================================
--- name-lookup.c	(revision 247647)
+++ name-lookup.c	(working copy)
@@ -37,6 +37,8 @@ static cxx_binding *cxx_binding_make (tr
 static cp_binding_level *innermost_nonclass_level (void);
 static void set_identifier_type_value_with_scope (tree id, tree decl,
 						  cp_binding_level *b);
+static void set_namespace_binding (tree name, tree scope, tree val);
+
 /* The bindings for a particular name in a particular scope.  */
 
 struct scope_binding {
@@ -213,7 +215,7 @@ arg_assoc_namespace (struct arg_lookup *
       if (arg_assoc_namespace (k, TREE_PURPOSE (value)))
 	return true;
 
-  value = namespace_binding (k->name, scope);
+  value = get_namespace_value (scope, k->name);
   if (!value)
     return false;
 
@@ -1248,7 +1250,7 @@ pushdecl_maybe_friend_1 (tree x, bool is
       /* In case this decl was explicitly namespace-qualified, look it
 	 up in its namespace context.  */
       if (DECL_NAMESPACE_SCOPE_P (x) && namespace_bindings_p ())
-	t = namespace_binding (name, DECL_CONTEXT (x));
+	t = get_namespace_value (DECL_CONTEXT (x), name);
       else
 	t = lookup_name_innermost_nonclass_level (name);
 
@@ -1265,7 +1267,7 @@ pushdecl_maybe_friend_1 (tree x, bool is
 	  t = innermost_non_namespace_value (name);
 	  /* Or in the innermost namespace.  */
 	  if (! t)
-	    t = namespace_binding (name, DECL_CONTEXT (x));
+	    t = get_namespace_value (DECL_CONTEXT (x), name);
 	  /* Does it have linkage?  Note that if this isn't a DECL, it's an
 	     OVERLOAD, which is OK.  */
 	  if (t && DECL_P (t) && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
@@ -1519,7 +1521,7 @@ pushdecl_maybe_friend_1 (tree x, bool is
 	{
 	  tree decl;
 
-	  decl = IDENTIFIER_NAMESPACE_VALUE (name);
+	  decl = get_namespace_value (current_namespace, name);
 	  if (decl && TREE_CODE (decl) == OVERLOAD)
 	    decl = OVL_FUNCTION (decl);
 
@@ -1556,7 +1558,7 @@ pushdecl_maybe_friend_1 (tree x, bool is
 		  || TREE_CODE (x) == NAMESPACE_DECL
 		  || TREE_CODE (x) == CONST_DECL
 		  || TREE_CODE (x) == TEMPLATE_DECL))
-	    SET_IDENTIFIER_NAMESPACE_VALUE (name, x);
+	    set_namespace_binding (name, current_namespace, x);
 
 	  /* If new decl is `static' and an `extern' was seen previously,
 	     warn about it.  */
@@ -1566,7 +1568,7 @@ pushdecl_maybe_friend_1 (tree x, bool is
       else
 	{
 	  /* Here to install a non-global value.  */
-	  tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name);
+	  tree oldglobal = get_namespace_value (current_namespace, name);
 	  tree oldlocal = NULL_TREE;
 	  cp_binding_level *oldscope = NULL;
 	  cxx_binding *oldbinding = outer_binding (name, NULL, true);
@@ -1605,7 +1607,8 @@ pushdecl_maybe_friend_1 (tree x, bool is
 		oldlocal = DECL_SHADOWED_FOR_VAR (oldlocal);
 
 	      if (oldlocal == NULL_TREE)
-		oldlocal = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (d));
+		oldlocal
+		  = get_namespace_value (current_namespace, DECL_NAME (d));
 	    }
 
 	  /* If this is an extern function declaration, see if we
@@ -1969,7 +1972,7 @@ check_for_out_of_scope_variable (tree de
     shadowed = DECL_HAS_SHADOWED_FOR_VAR_P (shadowed)
       ? DECL_SHADOWED_FOR_VAR (shadowed) : NULL_TREE;
   if (!shadowed)
-    shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (decl));
+    shadowed = get_namespace_value (current_namespace, DECL_NAME (decl));
   if (shadowed)
     {
       if (!DECL_ERROR_REPORTED (decl))
@@ -2931,7 +2934,7 @@ push_overloaded_decl_1 (tree decl, int f
   int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL));
 
   if (doing_global)
-    old = namespace_binding (name, DECL_CONTEXT (decl));
+    old = get_namespace_value (DECL_CONTEXT (decl), name);
   else
     old = lookup_name_innermost_nonclass_level (name);
 
@@ -4016,20 +4019,22 @@ namespace_binding_1 (tree name, tree sco
   return binding ? binding->value : NULL_TREE;
 }
 
+/* Return the binding for NAME in NS.  If NS is NULL, look in
+   global_namespace.  */
+
 tree
-namespace_binding (tree name, tree scope)
+get_namespace_value (tree ns, tree name)
 {
-  tree ret;
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
-  ret = namespace_binding_1 (name, scope);
+  if (!ns)
+    ns = global_namespace;
+  tree ret = namespace_binding_1 (name, ns);
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
   return ret;
 }
 
-/* Set the binding value for name in scope.  */
-
 static void
-set_namespace_binding_1 (tree name, tree scope, tree val)
+set_namespace_binding (tree name, tree scope, tree val)
 {
   cxx_binding *b;
 
@@ -4047,13 +4052,16 @@ set_namespace_binding_1 (tree name, tree
     supplement_binding (b, val);
 }
 
-/* Wrapper for set_namespace_binding_1.  */
+/* Set NAME in the global namespace to VAL.  Does not add it to the
+   list of things in the namespace.  */
 
 void
-set_namespace_binding (tree name, tree scope, tree val)
+set_global_value (tree name, tree val)
 {
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
-  set_namespace_binding_1 (name, scope, val);
+
+  set_namespace_binding (name, global_namespace, val);
+
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 }
 
@@ -5815,7 +5823,7 @@ lookup_name_innermost_nonclass_level_1 (
 
   if (b->kind == sk_namespace)
     {
-      t = IDENTIFIER_NAMESPACE_VALUE (name);
+      t = get_namespace_value (current_namespace, name);
 
       /* extern "C" function() */
       if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST)
@@ -6467,7 +6475,7 @@ push_namespace (tree name)
   if (anon)
     {
       name = anon_identifier;
-      d = IDENTIFIER_NAMESPACE_VALUE (name);
+      d = get_namespace_value (current_namespace, name);
       if (d)
 	/* Reopening anonymous namespace.  */
 	need_new = false;
@@ -6476,7 +6484,7 @@ push_namespace (tree name)
   else
     {
       /* Check whether this is an extended namespace definition.  */
-      d = IDENTIFIER_NAMESPACE_VALUE (name);
+      d = get_namespace_value (current_namespace, name);
       if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)
 	{
 	  tree dna = DECL_NAMESPACE_ALIAS (d);
Index: name-lookup.h
===================================================================
--- name-lookup.h	(revision 247647)
+++ name-lookup.h	(working copy)
@@ -311,8 +311,8 @@ extern tree pushdecl_with_scope (tree, c
 extern tree lookup_name_prefer_type (tree, int);
 extern tree lookup_name_real (tree, int, int, bool, int, int);
 extern tree lookup_type_scope (tree, tag_scope);
-extern tree namespace_binding (tree, tree);
-extern void set_namespace_binding (tree, tree, tree);
+extern tree get_namespace_value (tree ns, tree id);
+extern void set_global_value (tree id, tree val);
 extern bool hidden_name_p (tree);
 extern tree remove_hidden_names (tree);
 extern tree lookup_qualified_name (tree, tree, int, bool, /*hidden*/bool = false);
@@ -342,26 +342,4 @@ extern tree innermost_non_namespace_valu
 extern cxx_binding *outer_binding (tree, cxx_binding *, bool);
 extern void cp_emit_debug_info_for_using (tree, tree);
 
-/* Set *DECL to the (non-hidden) declaration for ID at global scope,
-   if present and return true; otherwise return false.  */
-
-inline bool
-get_global_value_if_present (tree id, tree *decl)
-{
-  tree global_value = namespace_binding (id, global_namespace);
-  if (global_value)
-    *decl = global_value;
-  return global_value != NULL;
-}
-
-/* True is the binding of IDENTIFIER at global scope names a type.  */
-
-inline bool
-is_typename_at_global_scope (tree id)
-{
-  tree global_value = namespace_binding (id, global_namespace);
-
-  return global_value && TREE_CODE (global_value) == TYPE_DECL;
-}
-
 #endif /* GCC_CP_NAME_LOOKUP_H */
Index: pt.c
===================================================================
--- pt.c	(revision 247647)
+++ pt.c	(working copy)
@@ -24731,7 +24731,7 @@ make_constrained_auto (tree con, tree ar
 static tree
 listify (tree arg)
 {
-  tree std_init_list = namespace_binding (init_list_identifier, std_node);
+  tree std_init_list = get_namespace_value (std_node, init_list_identifier);
   tree argvec;
   if (!std_init_list || !DECL_CLASS_TEMPLATE_P (std_init_list))
     {    
Index: rtti.c
===================================================================
--- rtti.c	(revision 247647)
+++ rtti.c	(working copy)
@@ -202,10 +202,15 @@ build_headof (tree exp)
 static tree
 throw_bad_cast (void)
 {
-  tree fn = get_identifier ("__cxa_bad_cast");
-  if (!get_global_value_if_present (fn, &fn))
-    fn = push_throw_library_fn (fn, build_function_type_list (ptr_type_node,
-							      NULL_TREE));
+  static tree fn;
+  if (!fn)
+    {
+      tree name = get_identifier ("__cxa_bad_cast");
+      fn = IDENTIFIER_GLOBAL_VALUE (name);
+      if (!fn)
+	fn = push_throw_library_fn
+	  (name, build_function_type_list (ptr_type_node, NULL_TREE));
+    }
 
   return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
 }
@@ -216,14 +221,17 @@ throw_bad_cast (void)
 static tree
 throw_bad_typeid (void)
 {
-  tree fn = get_identifier ("__cxa_bad_typeid");
-  if (!get_global_value_if_present (fn, &fn))
+  static tree fn;
+  if (!fn)
     {
-      tree t;
-
-      t = build_reference_type (const_type_info_type_node);
-      t = build_function_type_list (t, NULL_TREE);
-      fn = push_throw_library_fn (fn, t);
+      tree name = get_identifier ("__cxa_bad_typeid");
+      fn = IDENTIFIER_GLOBAL_VALUE (name);
+      if (!fn)
+	{
+	  tree t = build_reference_type (const_type_info_type_node);
+	  t = build_function_type_list (t, NULL_TREE);
+	  fn = push_throw_library_fn (name, t);
+	}
     }
 
   return build_cxx_call (fn, 0, NULL, tf_warning_or_error);

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2017-05-23 19:38 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-23 19:47 [C++ PATCH] namespace bindings Nathan Sidwell
  -- strict thread matches above, loose matches on Subject: below --
2017-05-05 20:25 Nathan Sidwell
2017-05-08 12:41 ` Andreas Schwab
2017-05-08 13:14   ` Nathan Sidwell
2017-05-08 14:33   ` Nathan Sidwell
2017-05-08 15:25     ` Andreas Schwab
2017-05-08 17:03       ` Nathan Sidwell
2017-05-08 13:06 ` Jason Merrill via gcc-patches
2017-05-08 13:34   ` Nathan Sidwell
2017-05-08 15:54   ` Nathan Sidwell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).