llvm / llvm/llvm-project

P2115R0: enumerations with enumerator as their name for linkage purposes, and their mangling

Open
#198,271 3 comments 0 reactions 0 assignees View on GitHub
c++20 clang:frontend diverges-from:gcc
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

A C++20 paper [P2115R0](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2115r0.html) "US069: Merging of multiple definitions for unnamed unscoped enumerations" gave linkage to unnamed enums declared outside of typedefs ([[basic.link]/4.5](https://eel.is/c++draft/basic.link#4.5)). It suggests that `namespace X { enum { A }; }` should be mangled as `_ZN1X1AE`, yet the new wording in [dcl.enum]/11 says that

> An unnamed enumeration that does not have a typedef name for linkage purposes (9.2.3) and that has a first enumerator is denoted, for linkage purposes (6.6), **_by its underlying type and its first enumerator_**; such an enumeration is said to have an enumerator as a name for linkage purposes.

(emphasis mine). Note that the suggested mangling doesn't contain `i` or `j` to indicate an underlying type of `int` or `unsigned int`.

Despite us claiming support for P2115R0 in #147489, we don't recognize such enums as having a name for linkage purpose, and mangle them as unnamed enums: `_ZN1X3$_0E`.

A year ago GCC landed a patch https://github.com/gcc-mirror/gcc/commit/7921bb4afcb7a3be8e10e63b10acfc2bfa477cae#diff-5823c562fd90bbcb99c08ed38a4346449b4c6fbee93cf872d6c23403e552d445, which changed the mangling of such enums to `_ZN1XUej1AE`, inventing a new mangling for unnamed enums:

> ` ::= Ue `

Before that they were doing the same thing as we currently do, but differently: `_ZN1X8._anon_0E`. This change has shipped in GCC 16.

On MSVC side the situation is different. MSVC has been mangling those enums using the name of the first enumerator (but not the underlying type!) for quite a while (in every version that Compiler Explorer offers, which goes back to 19.20), and we've been following that for 9 years at this point (https://github.com/llvm/llvm-project/commit/a5cfddc3679166619d4d553377b835df704e7269): `"??$f@W4@X@@@@YAHXZ"` (this is a mangling for a bigger name that contains `A::X`, but I don't know Microsoft mangling enough to strip unneeded parts: https://godbolt.org/z/r1z7rbK5s).

Questions I'd like to raise are:
1. Do we still want to claim full support of P2115R0 on our C++ status page?
2. Do we want to follow GCC and change our Itanium mangling of such enums?

I'm inclined to answer "no" and "yes", respectively, but I don't know enough mangling to be sure that GCC does the right thing.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.