[cfe-dev] ElaboratedType, QualifiedNameType and TypenameType.

Douglas Gregor dgregor at apple.com
Mon Mar 22 17:13:54 PDT 2010


On Mar 22, 2010, at 4:11 PM, Douglas Gregor wrote:

> 
> On Mar 22, 2010, at 3:45 PM, Abramo Bagnara wrote:
> 
>> Il 22/03/2010 23:27, Douglas Gregor ha scritto:
>>> 
>>> On Mar 22, 2010, at 3:15 PM, Abramo Bagnara wrote:
>>> 
>>>> Il 22/03/2010 21:10, Douglas Gregor ha scritto:
>>>>> 
>>>>> 
>>>>> There is an option (C). Here's what I think each of the types
>>>>> should do:
>>>>> 
>>>>> ElaboratedType: Should handle all elaborated-type-specifiers in
>>>>> the C++0x sense, which means a type referenced via the 
>>>>> enum/class/struct/union keyword. This class should be extended
>>>>> with an optional NestedNameSpecifier to handle qualified 
>>>>> elaborated-type-specifiers, ideally in a implementation-detail
>>>>> base class so that we don't pay a size penalty for "struct X".
>>>>> Getting this right should make fixing PR5681 trivial.
>>>> 
>>>> Why don't have ElaboratedType of QualifiedNameType instead of
>>>> optional NNS?
>>>> 
>>>> It seems to me it would be more congruent:
>>>> 
>>>> 1) ElaboratedType of EnumType (for non qualified enum X) 2)
>>>> ElaboratedType of QualifiedNameType of EnumType (for qualified not 
>>>> dependent enum A::X) 3) ElaboratedType of TypenameType (for
>>>> qualified dependent enum A::X)
>>> 
>>> 
>>> The problem is that elaborated-type-specifiers in the C++ language
>>> have very different name-lookup semantics than
>>> QualifiedNameType/TypenameType (C++ [basic.lookup.elab]), so it's
>>> cleaner to have the *Type nodes match up with language constructs.
>>> That's actually what
>>> 
>>> http://llvm.org/bugs/show_bug.cgi?id=5681
>>> 
>>> is about: we're using ElaboratedType as an outer level of sugar (more
>>> like what you're proposing than what I'm proposing), and because of
>>> that we get name-lookup wrong when we instantiate the node that the
>>> ElaboratedType points to. Instead, we should have enough information
>>> in the ElaboratedType itself to perform instantiation and
>>> elaborated-type-specifier name lookup without having to dig deeper
>>> into the type that the ElaboratedType points to.
>> 
>> I guess I've misunderstood something...
>> 
>> Tell me where I'm wrong:
>> 
>> - non qualified enum X would be represented as ElaboratedType of
>> EnumType (exactly as now)
> 
> It's an ElaboratedType whose canonical type is an EnumType.
> 
>> - qualified not dependent enum A::X would be represented as
>> ElaboratedType of EnumType using the (to be inserted) optional NNS
> 
> Yes, same thing (the canonical type is an EnumType).
> 
>> - qualified dependent enum A::X ???
>> 
>> Here I'm lost, from your previous message I believed you want to leave
>> it as now (ElaboratedType of TypenameType), but now I thought I've
>> misunderstood (as PR5681 is related to this case).
> 
> 
> I wanted this to be an ElaboratedType... but it's a completely different kind of elaborated type than the first two cases. Actually, I'm coming around to the idea of TypenameType morphing into some kind of DependentQualifiedNameType node, which covers typename/class/struct/enum. The lookup is different for those cases, but otherwise it gets the point across.


... and after talking with John for a bit, we're starting to like the following scheme:

DependentQualifiedNameType: captures all qualified types with dependent names, including elaborated-type-specifiers (class/struct/union/enum), typename-specifiers (typename), and implied dependent name types (X<T>::type as a base class).

ElaboratedType: captures all elaborated-type-specifiers (class/struct/union/enum), typename-specifiers (typename), and qualified names (no other adornment) where we were able to look up the type. These nodes can have an optional NestedNameSpecifier, and will always have either a class/struct/union/enum keyword or a nested-name-specifier.

	- Doug



More information about the cfe-dev mailing list