[cfe-dev] Implementing P1099R5 (using enum) in clang

David Rector via cfe-dev cfe-dev at lists.llvm.org
Fri Jul 10 17:03:42 PDT 2020


Scratch that, I already see the problem: suppose one of those enums was not scoped, i.e. 

enum fruit { orange, apple };
enum class fruitB { apple, orange, pear; };

template<typename FRUIT_IMPL>
struct S {
  using enum FRUIT_IMPL; // really is bad, because...
  static const auto val = orange; // this would be resolved to fruit::orange, not FRUIT_IMPL::orange
};

void f() {
  S<fruitB> s2;
  s2.orange //refers to fruit::orange, not fruitB::orange, whoops
}

So no dependent case of UsingEnumDecl after all.  Thanks Richard and good luck Shachaf,

- Dave 


> On Jul 10, 2020, at 7:55 PM, David Rector <davrecthreads at gmail.com> wrote:
> 
> 
> 
>> On Jul 10, 2020, at 6:36 PM, Richard Smith <richard at metafoo.co.uk <mailto:richard at metafoo.co.uk>> wrote:
>> 
>> On Fri, 10 Jul 2020 at 15:09, David Rector via cfe-dev <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>> wrote:
>> ...
>> Note you’ll also need an UnresolvedUsingEnumDecl for e.g. "using enum T::someenum" when T is dependent; in TreeTransfomr::… you may transform that to your UsingEnumDecl when T becomes non-dependent; follow the example of e.g. UnresolvedUsingTypenameDecl I believe it is.
>> 
>> We don't need that in this case, because the language rules don't permit `using enum A::B;` to name a dependent type. (The reason it's disallowed is that it would create major implementation problems -- we couldn't reasonably do unqualified lookups in a scope that contains such a declaration because we'd have no idea if the name resolves to an enumerator.)
> 
> Is that rule really necessary though?  Why not allow the dependent enum itself and let lookup fail for the enumerators, just until it finally is transformed into a resolved UsingEnumDecl?  E.g.:
> 
> ```
> enum class fruit  { orange, apple };
> enum class fruitB { orange, apple, pear };
> 
> template<typename FRUIT_IMPL>
> struct S {
>   using enum FRUIT_IMPL; //why does this need to be an error?
>   static const auto BadVal = orange; //Definitely an error, undeclared ID "orange"; shouldn’t this suffice?
>   static const auto GoodVal = FRUIT_IMPL::orange; // This should be okay though, since still dependent.
> };
> 
> void f() {
>   S<fruit> s;
>   s.orange;
> 
>   S<fruitB> s2;
>   s2.pear;
> }
> ```
> 
> I couldn’t find an explanation on the page Shachaf referenced.  In any case, if there is no need to handle a dependent case this should be very straightforward, Shachaf.  Good luck,
> 
> - Dave
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200710/4cfa1f70/attachment-0001.html>


More information about the cfe-dev mailing list