Fix bindings for using declarations. When an identifier is declared in a using declaration, we were registering the USING_DECL object in the corresponding binding.
This was wrong, and at the time I hacked around it by simply ignoring USING_DECLs when setting bindings. That was wrong too. What we actually need to do is discover what is the USING_DECL pointing to and register that. I traced the regular parser, and I'm mimicking the lookup of the associated TYPE_DECL by calling do_nonmember_using_decl. The only issue I have with this is that I'm not sure where to get the scope from. In the testcase I'm fixing, the USING_DECL's type has the namespace_decl where the search should be done. I'll test in the internal codebase and see if this is always the case. 2012-03-23 Diego Novillo <dnovi...@google.com> cp/ChangeLog.pph * name-lookup.c (pph_set_identifier_binding): If DECL is a USING_DECL, register the TYPE_DECL it is referring to. (pph_set_namespace_decl_binding): Remove previous hack that skipped USING_DECLs. testsuite/ChangeLog.pph * g++.dg/pph/x1mbstate_t.h: Mark fixed. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 1b33ce3..26d4f86 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -6197,15 +6197,27 @@ pph_set_identifier_binding (tree id, tree decl, cp_binding_level *bl, int flags) { tree old_value; + cxx_binding *b; /* FIXME pph: This code plagarizes from push_overloaded_decl_1 and binding_for_name. It may be incomplete. */ - - cxx_binding *b = cp_binding_level_find_binding_for_name (bl, id); + b = cp_binding_level_find_binding_for_name (bl, id); if (!b) { b = cxx_binding_make_for_name (bl, id); - b->value = decl; + if (TREE_CODE (decl) == USING_DECL) + { + /* USING_DECLs cannot be registered into the binding. Instead, we + look up the TYPE_DECL it is pointing to by calling + do_nonmember_using_decl. */ + tree new_value, new_type; + do_nonmember_using_decl (TREE_TYPE (decl), id, b->value, b->type, + &new_value, &new_type); + b->value = new_value; + b->type = new_type; + } + else + b->value = decl; pph_debug_binding_action ("new bind", decl); return; } @@ -6271,11 +6283,7 @@ pph_set_namespace_decl_binding (tree decl, cp_binding_level *bl, int flags) { /* Set the namespace identifier binding for a single decl. */ tree id = DECL_NAME (decl); - /* FIXME pph. USING_DECLs do not seem to be used in bindings by - the parser. This was causing the SEGV in - testsuite/g++.dg/pph/x1mbstate_t.h. It's unclear whether this is - the right fix. */ - if (id && TREE_CODE (decl) != USING_DECL) + if (id) pph_set_identifier_binding (id, decl, bl, flags); } diff --git a/gcc/testsuite/g++.dg/pph/x1mbstate_t.h b/gcc/testsuite/g++.dg/pph/x1mbstate_t.h index 69323d1..4d473e4 100644 --- a/gcc/testsuite/g++.dg/pph/x1mbstate_t.h +++ b/gcc/testsuite/g++.dg/pph/x1mbstate_t.h @@ -1,10 +1,8 @@ -// { xfail-if "" { "*-*-*" } { "-fpph-map=pph.map" } } - #ifndef _X1_MBSTATE_H #define _X1_MBSTATE_H #include "x0mbstate_t.h" // Name lookup for std::mbstate_t was failingfails here. Instead of returning // the global type_decl for mbstate_t, it was returning the // "usings ::mbstate_t" declaration. -typedef std::mbstate_t state_type; // { dg-bogus "'mbstate_t' in namespace 'std' does not name a type" "" { xfail *-*-* } } +typedef std::mbstate_t state_type; #endif -- This patch is available for review at http://codereview.appspot.com/5900043