diff mbox

[C++] inline & using namespace representation

Message ID 84b100df-c969-3f29-006f-f046623c37b1@acm.org
State New
Headers show

Commit Message

Nathan Sidwell May 26, 2017, 5:24 p.m. UTC
This patch changes the representation of a namespace's inline children 
and using directives.

Using directive were a TREE_LIST, which (a) held the complete graph and 
(b) noted the common ancestor.  We now need neither of them

Inline children were in the using directive list too, but then I 
stripped them out of there, and one had to look down the namespace 
binding list.  Which isn't the best.

The patch makes both a vector of tree, held on lang_decl_ns.  Remember I 
just removed the ns_user member from there, so this isn't an increase in 
size over all.  All the uses of these fields are fixed up in the obvious 
way.

nathan
diff mbox

Patch

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

	gcc/cp/
	Inline and using namespace representation change.
	* cp-tree.h (struct lang_decl_ns): Delete ns_using.  Add usings,
	inlinees as vector.
	(DECL_NAMESPACE_USING): Adjust.
	(DECL_NAMESPACE_INLINEES): New.
	* name-lookup.h (struct cp_binding_level): Change usings
	representation.
	* name-lookup.c (name_lookup::do_queue_usings,
	name_lookup::queue_usings): Adjust.
	(name_lookup::search_namespace, name_lookup::search_usings,
	name_lookup::queue_namespace): Adjust.
	(name_lookup::adl_namespace_only): Adjust.
	(add_using_namespace, push_namespace): Push onto vector.
	(pop_namespace): Add timing logic.

	libcc1/
	* libcp1plugin.cc (plugin_make_namespace_inline): Push onto linees.

Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 248517)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -2546,7 +2546,11 @@  struct GTY(()) lang_decl_fn {
 struct GTY(()) lang_decl_ns {
   struct lang_decl_base base;
   cp_binding_level *level;
-  tree ns_using;
+
+  /* using directives and inline children.  These need to be va_gc,
+     because of PCH.  */
+  vec<tree, va_gc> *usings;
+  vec<tree, va_gc> *inlinees;
 };
 
 /* DECL_LANG_SPECIFIC for parameters.  */
@@ -3133,10 +3137,13 @@  struct GTY(()) lang_decl {
 #define DECL_NAMESPACE_INLINE_P(NODE) \
   TREE_LANG_FLAG_0 (NAMESPACE_DECL_CHECK (NODE))
 
-/* For a NAMESPACE_DECL: the list of using namespace directives
-   The PURPOSE is the used namespace, the value is the namespace
-   that is the common ancestor.  */
-#define DECL_NAMESPACE_USING(NODE) (LANG_DECL_NS_CHECK (NODE)->ns_using)
+/* In a NAMESPACE_DECL, a vector of using directives.  */
+#define DECL_NAMESPACE_USING(NODE) \
+   (LANG_DECL_NS_CHECK (NODE)->usings)
+
+/* In a NAMESPACE_DECL, a vector of inline namespaces.  */
+#define DECL_NAMESPACE_INLINEES(NODE) \
+   (LANG_DECL_NS_CHECK (NODE)->inlinees)
 
 /* In a NAMESPACE_DECL, points to the original namespace if this is
    a namespace alias.  */
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c	(revision 248518)
+++ gcc/cp/name-lookup.c	(working copy)
@@ -220,8 +220,10 @@  private:
 
 private:
   using_queue *queue_namespace (using_queue *queue, int depth, tree scope);
-  using_queue *do_queue_usings (using_queue *queue, int depth, tree usings);
-  using_queue *queue_usings (using_queue *queue, int depth, tree usings)
+  using_queue *do_queue_usings (using_queue *queue, int depth,
+				vec<tree, va_gc> *usings);
+  using_queue *queue_usings (using_queue *queue, int depth,
+			     vec<tree, va_gc> *usings)
   {
     if (usings)
       queue = do_queue_usings (queue, depth, usings);
@@ -496,11 +498,10 @@  name_lookup::search_namespace (tree scop
   /* Look in exactly namespace. */
   bool found = search_namespace_only (scope);
   
-  /* Look down into inline namespaces.  */
-  for (tree inner = NAMESPACE_LEVEL (scope)->namespaces;
-       inner; inner = TREE_CHAIN (inner))
-    if (DECL_NAMESPACE_INLINE_P (inner))
-      found |= search_namespace (inner);
+  /* Recursively look in its inline children.  */
+  if (vec<tree, va_gc> *inlinees = DECL_NAMESPACE_INLINEES (scope))
+    for (unsigned ix = inlinees->length (); ix--;)
+      found |= search_namespace ((*inlinees)[ix]);
 
   if (found)
     mark_found (scope);
@@ -520,17 +521,14 @@  name_lookup::search_usings (tree scope)
     return true;
 
   bool found = false;
-
-  /* Look in direct usings.  */
-  for (tree usings = DECL_NAMESPACE_USING (scope);
-       usings; usings = TREE_CHAIN (usings))
-    found |= search_qualified (TREE_PURPOSE (usings), true);
+  if (vec<tree, va_gc> *usings = DECL_NAMESPACE_USING (scope))
+    for (unsigned ix = usings->length (); ix--;)
+      found |= search_qualified ((*usings)[ix], true);
 
   /* Look in its inline children.  */
-  for (tree inner = NAMESPACE_LEVEL (scope)->namespaces;
-       inner; inner = TREE_CHAIN (inner))
-    if (DECL_NAMESPACE_INLINE_P (inner))
-      found |= search_usings (inner);
+  if (vec<tree, va_gc> *inlinees = DECL_NAMESPACE_INLINEES (scope))
+    for (unsigned ix = inlinees->length (); ix--;)
+      found |= search_usings ((*inlinees)[ix]);
 
   if (found)
     mark_found (scope);
@@ -580,10 +578,9 @@  name_lookup::queue_namespace (using_queu
   vec_safe_push (queue, using_pair (common, scope));
 
   /* Queue its inline children.  */
-  for (tree inner = NAMESPACE_LEVEL (scope)->namespaces;
-       inner; inner = TREE_CHAIN (inner))
-    if (DECL_NAMESPACE_INLINE_P (inner))
-      queue = queue_namespace (queue, depth, inner);
+  if (vec<tree, va_gc> *inlinees = DECL_NAMESPACE_INLINEES (scope))
+    for (unsigned ix = inlinees->length (); ix--;)
+      queue = queue_namespace (queue, depth, (*inlinees)[ix]);
 
   /* Queue its using targets.  */
   queue = queue_usings (queue, depth, DECL_NAMESPACE_USING (scope));
@@ -594,10 +591,11 @@  name_lookup::queue_namespace (using_queu
 /* Add the namespaces in USINGS to the unqualified search queue.  */
 
 name_lookup::using_queue *
-name_lookup::do_queue_usings (using_queue *queue, int depth, tree usings)
+name_lookup::do_queue_usings (using_queue *queue, int depth,
+			      vec<tree, va_gc> *usings)
 {
-  for (; usings; usings = TREE_CHAIN (usings))
-    queue = queue_namespace (queue, depth, TREE_PURPOSE (usings));
+  for (unsigned ix = usings->length (); ix--;)
+    queue = queue_namespace (queue, depth, (*usings)[ix]);
 
   return queue;
 }
@@ -686,10 +684,9 @@  name_lookup::adl_namespace_only (tree sc
   mark_seen (scope);
 
   /* Look down into inline namespaces.  */
-  for (tree inner = NAMESPACE_LEVEL (scope)->namespaces;
-       inner; inner = TREE_CHAIN (inner))
-    if (DECL_NAMESPACE_INLINE_P (inner))
-      adl_namespace_only (inner);
+  if (vec<tree, va_gc> *inlinees = DECL_NAMESPACE_INLINEES (scope))
+    for (unsigned ix = inlinees->length (); ix--;)
+      adl_namespace_only ((*inlinees)[ix]);
 
   if (cxx_binding *binding = find_namespace_binding (scope, name))
     add_fns (ovl_skip_hidden (binding->value));
@@ -5962,13 +5959,14 @@  do_pop_nested_namespace (tree ns)
    the unqualified search.  */
 
 static void
-add_using_namespace (tree &usings, tree target)
+add_using_namespace (vec<tree, va_gc> *&usings, tree target)
 {
-  for (tree probe = usings; probe; probe = TREE_CHAIN (probe))
-    if (target == TREE_PURPOSE (probe))
-      return;
+  if (usings)
+    for (unsigned ix = usings->length (); ix--;)
+      if ((*usings)[ix] == target)
+	return;
 
-  usings = tree_cons (target, NULL_TREE, usings);
+  vec_safe_push (usings, target);
 }
 
 /* Tell the debug system of a using directive.  */
@@ -6142,8 +6140,14 @@  push_namespace (tree name, bool make_inl
 	  else if (TREE_PUBLIC (current_namespace))
 	    TREE_PUBLIC (ns) = 1;
 
+	  if (name == anon_identifier || make_inline)
+	    emit_debug_info_using_namespace (current_namespace, ns);
+
 	  if (make_inline)
-	    DECL_NAMESPACE_INLINE_P (ns) = true;
+	    {
+	      DECL_NAMESPACE_INLINE_P (ns) = true;
+	      vec_safe_push (DECL_NAMESPACE_INLINEES (current_namespace), ns);
+	    }
 	}
     }
 
@@ -6171,10 +6175,14 @@  push_namespace (tree name, bool make_inl
 void
 pop_namespace (void)
 {
+  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
+
   gcc_assert (current_namespace != global_namespace);
   current_namespace = CP_DECL_CONTEXT (current_namespace);
   /* The binding level is not popped, as it might be re-opened later.  */
   leave_scope ();
+
+  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 }
 
 /* External entry points for do_{push_to/pop_from}_top_level.  */
Index: gcc/cp/name-lookup.h
===================================================================
--- gcc/cp/name-lookup.h	(revision 248518)
+++ gcc/cp/name-lookup.h	(working copy)
@@ -194,9 +194,9 @@  struct GTY(()) cp_binding_level {
   /* A list of USING_DECL nodes.  */
   tree usings;
 
-  /* A list of used namespaces. PURPOSE is the namespace,
-      VALUE the common ancestor with this binding_level's namespace.  */
-  tree using_directives;
+
+  /* Using directives.  */
+  vec<tree, va_gc> *using_directives;
 
   /* For the binding level corresponding to a class, the entities
       declared in the class or its base classes.  */
Index: libcc1/libcp1plugin.cc
===================================================================
--- libcc1/libcp1plugin.cc	(revision 248518)
+++ libcc1/libcp1plugin.cc	(working copy)
@@ -934,6 +934,7 @@  plugin_make_namespace_inline (cc1_plugin
     return 0;
 
   DECL_NAMESPACE_INLINE_P (inline_ns) = true;
+  vec_safe_push (DECL_NAMESPACE_INLINEES (parent_ns), inline_ns);
 
   return 1;
 }