[cxx-abi-dev] namespace-qualified unresolved-names

James Widman widman at gimpel.com
Mon Apr 25 16:59:20 UTC 2011


On 24 Apr 2011, at 02:22, John McCall wrote:

> Consider the following:
> 
>  namespace ns {
>    int foo(int);
>    short foo(short);
>  }
> 
>  template <typename T> auto forward_foo(T t) -> decltype(ns::foo(t)) {
>    return ns::foo(t);
>  }
> 
>  short test(short x) { return forward_foo(x); }
> 
> gcc-4.6 mangles forward_foo<short> as:
>  _Z11forward_fooIsEDTcl3foofp_EET_
> 
> This seems obviously wrong:  the qualifier has completely disappeared,
> and this now looks like an unqualified call.  I believe the correct
> mangling falls under the fourth production for <unresolved-name>:
>  <unresolved-name> ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
> In that case, the mangling should be:
>  _Z11forward_fooIsEDTclsr2nsE3foofp_EET_

I'm not sure if that's completely right (because I haven't carefully read the current mangling rules), but I am pretty sure that "2ns" needs to be there.

> Right?  I just want to verify that, because I have some follow-ups. :)
> 
> 1. When mangling a namespace qualifier for an unresolved-name,
> should we mangle the full namespace path or just what was written?
>  namespace outer {
>    namespace ns { ... }
>    template <typename T> auto forward_foo(T t) -> decltype(ns::foo(t));
>    // sr2nsE3foo or sr5outer2nsE3foo or gssr5outer2nsE3foo ?
>  }

I think the answer is "just what was written" (i.e., you use the raw sequence of tokens) because of 14.4 [temp.type] p2:

        If an expression e involves a template parameter,
        decltype(e) denotes a unique dependent type. Two such
        /decltype-specifiers/ refer to the same type only if their
        /expression/s [grammar term] are equivalent (14.5.6.1).
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        [Note: however, it may be aliased, e.g., by a
        typedef-name. end note ]

So the type given by:

   decltype(inner::foo(t))

... is not the type given by:

   decltype(outer::inner::foo(t))

... because the /expression/s are different (because the token sequences are different).

> The 'gs' does not seem to be useful in the case of a non-member
> unresolved-name with a qualifier.
> 
> 2. Should we look through template aliases?
>  namespace alias = ns;

(That's a namespace alias [namespace.alias], although it's good to consider namespace aliases in addition to alias templates [temp.alias].)

>  template <typename T> auto forward_foo(T t) -> decltype(alias::foo(t));
>  // sr2nsE3foo or sr5aliasE3foo ?

Again, I think 14.4 implies the use of the raw sequence of tokens.  So no, you don't look through aliases.

> 2a. If we look through template aliases, what happens to prefix
> nested name specifiers?
>  namespace nsx { namespace alias = ns; }
>  template <typename T> auto forward_foo(T t) -> decltype(nsx::alias::foo(t));
>  // sr2nsE3foo ?

Ditto.

> 2b. Specifically, what about global prefixes?
>  template <typename T> auto forward_foo(T t) -> decltype(::alias::foo(t));
>  // sr2nsE3foo or gssr2nsE3foo ?

Ditto.

James Widman  
-- 
Gimpel Software 
http://gimpel.com






More information about the cxx-abi-dev mailing list