This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Data structure for using directive
- From: Gabriel Dos Reis <gdr at integrable-solutions dot net>
- To: gcc at gcc dot gnu dot org
- Cc: mark at codesourcery dot com, jason at redhat dot com, nathan at codesourcery dot com
- Date: 03 Sep 2002 18:41:57 +0200
- Subject: Data structure for using directive
- Organization: Integrable Solutions
Hi,
Consider C++ PR/2455 :
namespace A { }
namespace B { using namespace A; }
namespace A { using namespace B; }
void f() { using namespace B; }
This has the remarkable property of sending cc1plus into an infinite
loop because of the following:
/* Add namespace to using_directives. Return NULL_TREE if nothing was
changed (i.e. there was already a directive), or the fresh
TREE_LIST otherwise. */
tree
push_using_directive (used)
tree used;
{
tree ud = current_binding_level->using_directives;
tree iter, ancestor;
/* Check if we already have this. */
if (purpose_member (used, ud) != NULL_TREE)
return NULL_TREE;
/* Recursively add all namespaces used. */
for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
push_using_directive (TREE_PURPOSE (iter));
ancestor = namespace_ancestor (current_decl_namespace (), used);
ud = current_binding_level->using_directives;
ud = tree_cons (used, ancestor, ud);
current_binding_level->using_directives = ud;
return ud;
}
I think that handling of using-directives is no good:
1) In the favorable case, each time we encounter a using-directive
we go through and push the used-namespace and the namespaces it
uses into the set of used-namespaces of the namespace enclosing the
using-directive. Therefore duplicating information. An
immediate consequence is that we end up using an extra bit for
distinguishing a directly used namespace from an indirectly
used-namespace. An inconvenient artefact.
2) In the worst situation like PR/2455, we go into infinite loop
because upon
namespace A { using namespace B; }
we insist on pushing the namespaces used by B (here A) into the
set of used namespace of A an recursively :-(
I think a better approach would be using a splay_tree to store the
used-namespace as the KEY and the common ancestor as the VALUE. This
has the following benefit:
1) no opportunity of going into infinite loop
2) no need for an extra word for distinguishing a directly-used
from an indirectly-used namespace.
The above requires me changing DECL_NAMESPACE_USING use a field of a
'struct tree_decl' that has a compatible-type (or that can be made so)
with splay_tree. I'm thinking of DECL_POINTER_ALIAS_SET. Thoughts?
-- Gaby