This is an archive of the discontinued LLVM Phabricator instance.

using-enum part 2 (RFC)
AbandonedPublic

Authored by urnathan on Apr 27 2021, 8:53 AM.

Details

Summary

This is a WIP for the second part of p1099, namely the 'using elaborated-enum-specifier ;' part. It's a WIP because I'd like advice on resolving some FIXMEs in the diff.

I added the parsing to ParseUsingDeclaration, even though the grammar describes a using-enum as a different kind of construct. It seems simplest to disambiguate it there, and AFAICT using-enum is valid in all the places a regular using decl is.

I still use a UsingDecl to represent the using-enum, and add some accessors and a new field to that (this is one of the FIXMEs, see the comment in the diff explaining further).

For instantiation, we can meet an uncompleted scoped enum. There doesnt seem to be a good routine to complete that case, Again a FIXME notes that RequireCompleteDeclContext wants a ScopeRef, which we don't have at the needed point.

There is some similarity and some differences with a using-enum vs regular using, and perhaps some helper routines might be broken out?

Diff Detail

Event Timeline

urnathan requested review of this revision.Apr 27 2021, 8:53 AM
urnathan created this revision.
urnathan added inline comments.Apr 27 2021, 9:05 AM
clang/include/clang/AST/DeclCXX.h
3389

I considered a new UsingEnumDecl, but we still have the same chain of shadow decls to maintain, so that'd mean also breaking out the shadow list iterator stuff. Perhaps if we stored 2 bits in the shadowdecl pointer/int pair, and held a discriminator there, then the Enum field could overlay the QualifierLoc and DNLoc?

3415

No point altering the streamers before the data organization is settled.

3444

IIUC these accessors should assert they're being used on the right dynamic type

clang/lib/Parse/ParseDeclCXX.cpp
695–696

this block is copied from the regular using-decl parsing below. It was more awkward making the control flow work with a single block.

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
3026

It seems that using-enum results in a place where we need to complete a scoped-enumerator, but not for regular scope lookup within the enum, so we do not have a ScopeSpec around. I copied this block from RequireCompleteDeclContext, but (a) copying makes me sad and (b) I'm concerned about failure modes. what to do?

3052

This loop is very like the regular using-decl loop below. Like the parser, trying to make control flow for the two cases reach a single loop was awkward -- there's a LookupResult object that's live in that case, and here only within an iteration. It seems parameterizing a helper would work though?

aaron.ballman added inline comments.Apr 30 2021, 7:14 AM
clang/include/clang/AST/DeclCXX.h
3389

That approach sounds plausible to me.

Perhaps another possible approach would be to use trailing objects on the UsingDecl so that you'll either have a trailing object of EnumDecl * or the previous fields.

3444

Agreed.

clang/lib/Parse/ParseDeclCXX.cpp
687–688

We usually do an awkward (to me) diagnostic dance in these situations where we give a "not compatible with previous standards" warning or a "is a C++whatever extension" warning.

e.g., https://github.com/llvm/llvm-project/blob/main/clang/lib/Parse/ParseDeclCXX.cpp#L2842

Plan of action is to follow https://lists.llvm.org/pipermail/cfe-dev/2021-April/068074.html, break a ShadowIntroducingDecl base out of UsingDecl and then add UsingEnumDecl derived from that.

urnathan abandoned this revision.May 11 2021, 7:47 AM

oops, created a new revision for the update