In the Itanium C++ ABI, why does the mangled name for template functions not resolve dependent typedefs?

c++, itanium-abi, name-mangling, templates

Solution

The issue comes from the `<unresolved-name>` construct in the ABI. Why would we ever want to use an unresolved name? It's all about declaration matching and overloads. C++14 §14.5.6.1/3 notes,

Two distinct function templates may have identical function return types and function parameter lists, even if overload resolution alone cannot distinguish them.

You can have another function in a different file,

template <typename T>
void baz(int quux) { std::abort(); }

Although this signature can't peacefully coexist in the same file — it cannot be named because of overload ambiguity — it can exist in a different file so it needs a distinct mangling.

(Even this level of coexistence is not guaranteed by the standard for all templates. It's a matter of QOI that the compiler uses the exact form of a function template declaration to perform declaration matching, so that copy-pasting a declaration into a definition will tend to provide an exact match and not a surprising conflict with another function template that resolves to the same signature. See §14.5.6.1/5-6.)

As for raining on `default_order`'s parade, the problem is that template-ids implicitly pull default arguments from templates. So the user could unintentionally have a dependent typename in a signature just by mentioning `std::set`.

Problem

For example: ``` template <typename T> struct foo { using bar = int; }; // _Z3bazi void baz(foo<int>::bar quux) { } template <typename T> void baz(typename foo<T>::bar quux) { } // _Z3bazIiEvN3fooIT_E3barE template void baz<int>(foo<int>::bar quux); ``` Why does the mangled form of `baz<int>` mention `foo` at all? How come it's not `_Z3bazIiEvi`? This is apparently the reason that the C++17 `std::default_order<T>` proposal is dead in the water.

Original source