https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88413

--- Comment #8 from brennan at umanwizard dot com ---
Yes that is the literal srN string and in fact GCC does output that sometimes,
for example on the following program which made it a lot clearer to me what is
going on.

template <int i>
struct S1 {
};

struct S2
{
  template <typename T>
  struct S3 {
    static constexpr int val = sizeof(T);
  };
};

template <typename T>
void g(S1<S2::S3<T>::val> * = nullptr) {
}

void h() {
  g<int>();
}

in which g<int> is mangled as __Z1gIiEvP2S1IXsrN2S22S3IT_EE3valEE . Clang
mangles it as __Z1gIiEvP2S1IXsr2S22S3IT_EE3valEE -- notice there is no "N" in
Clang's version. Again I feel Clang is correct, based on my understanding of
the standard.

GCC apparently uses only the two productions
<unresolved-name> ::= sr <unresolved-type> <base-unresolved-name>     # T::x /
decltype(p)::x
<unresolved-name> ::= srN <unresolved-type> <unresolved-qualifier-level>+ E
<base-unresolved-name>
                                                    # T::N::x
/decltype(p)::N::x

But if you look up "unresolved-type" in the standard, it is clear that those
two productions should only be used when the first element in the chain is a
template parameter, not some random class or namespace. So it is wrong to
encode "S2::S3<T>::val" with either of those, because "S2" is not an
"<unresolved-type>". Presumably this is what the standard authors were getting
at by using the letter "T" in the comment.

The production GCC should be using in that program, and the one Clang actually
does use, is:

<unresolved-name> ::= [gs] sr <unresolved-qualifier-level>+ E
<base-unresolved-name>  
                                                                        # A::x,
N::y, A<T>::z; "gs" means leading "::"

In S2::S3<T>::val, each of S2 and S3<T> is an "<unresolved-qualifier-level>"
and val is a "<base-unresolved-name>".

Reply via email to