Introduce the following optimizations in DeclarationName(Table)
- Store common kinds inline in DeclarationName instead of DeclarationNameExtra. Currently the kind of C++ constructor, destructor, conversion function and overloaded operator names is stored in DeclarationNameExtra. Instead store it inline in DeclarationName. To do this align IdentifierInfo, CXXSpecialName, DeclarationNameExtra and CXXOperatorIdName to 8 bytes so that we can use the lower 3 bits of DeclarationName::Ptr. This is already the case on 64 bits archs anyway. This also allow us to remove DeclarationNameExtra from CXXSpecialName and CXXOperatorIdName, which shave off a pointer from CXXSpecialName. (This might be the thing that sink this patch since you might judge that aligning IdentifierInfo to 8 bytes even on 32 bits archs is not acceptable. Although if we care about 32 bits archs there is probably a lot more that can be done.)
- Synchronize the enumerations DeclarationName::NameKind, DeclarationName::StoredNameKind and Selector::IdentifierInfoFlag. This makes DeclarationName::getNameKind much more efficient since we can replace the switch table by a single comparison and an addition. static_asserts are provided in DeclarationName::VerifyStaticAsserts to ensure that the enumerations remain in sync.
- Put the overloaded operator names inline in DeclarationNameTable to remove an indirection. This increase the size of DeclarationNameTable a little bit but this is not important since it is only used in ASTContext, and never copied nor moved from. This also get rid of the last dynamic allocation in DeclarationNameTable.
Altogether these optimizations cut the run time of parsing all of Boost by about 0.8%.
While we are at it, do the following NFC modifications:
- Put the internal classes CXXSpecialName, CXXDeductionGuideNameExtra, CXXOperatorIdName, CXXLiteralOperatorIdName and DeclarationNameExtra in a namespace detail since these classes are only meant to be used by DeclarationName and DeclarationNameTable. Make this more explicit by making the members of these classes private and friending DeclarationName(Table).
- Make DeclarationName::getFETokenInfo a non-template since every users are using it to get a void *. It was supposed to be used with a type to avoid a subsequent static_cast.
- Change the internal functions DeclarationName::getAs* to castAs* since when we use them we already know the correct kind. This has no external impact since all of these are private.
Should DeclarationNameExtra be moved here? I'm not sure why it's in IdentifierTable.h in the first place, and your refactor seems to make that even more pointless.