[cfe-dev] ElaboratedType, QualifiedNameType and TypenameType.
Douglas Gregor
dgregor at apple.com
Mon Mar 22 13:10:42 PDT 2010
On Mar 22, 2010, at 3:58 AM, Enea Zaffanella wrote:
> Hello.
>
> We were looking into these three AST classes (while wearing the glasses
> of applications working at the source code level) and we ended up with
> the following picture:
>
> 1) An ElaboratedType is a type name prefixed by a tag keyword.
> The current clang implementation requires that this tag keyword is taken
> from the set { struct, class, union, enum }. This differs from the
> standard (C++98 7.1.5.3), where also the keyword 'typename' is allowed.
> The (optional) name qualifier is not directly encoded in the AST node.
The C++98/03 standard is very, very confusing here. The intent was not to make 'typename' abide by the rules in 7.1.5.3 [dcl.type.elab]; it was a syntactic convenience in the grammar.
I suggest that you instead look at C++0x, which has a "typename-specifier" grammar production for typename types that is completely distinct from elaborated-type-specifiers.
> 2) A QualifiedNameType is a non-dependent type name provided with a
> (mandatory) name qualifier. The current implementation does not encode
> the (optional) tag keyword, but there is a FIXME noting that, e.g., the
> 'typename' keyword could be used even though the name is not dependent
> (C++98 14.6p5).
The intent of QualifiedNameType is that it never have a tag; that should be handled by ElaboratedType.
> 3) A TypenameType is a dependent type name provided with a (mandatory)
> name qualifier. The current implementation does not encode the
> (mandatory) tag keyword, which will be tipically be 'typename', but
> could also be another one, as in the following example:
[snip]
> We would like to improve things in order to have an exact picture of
> what was written in the program. We have two options:
>
> A) allow for 'typename' in ElaboratedType and let these keywords be
> *always* encoded by ElaboratedType nodes. That is, variable x1, x2, y1
> and y2 will all have ElaboratedType, containing a TypenameType (x1 and
> y1) or a QualifiedNameType (x2 and y2). One may also consider the
> possibility of renaming class "TypenameType" to become
> "DependentNameType" (since the typename keyword is not actually implied).
>
> B) get rid of ElaboratedType nodes and push the corresponding info about
> the tag keyword down into QualifiedNameType (where the name qualifier
> would become optional) and TypenameType.
>
> To our eyes, option A) is closer to what is said in the C++ standard;
> however, option B would maybe require less AST nodes (of course, the
> inner nodes would become bigger).
> What is the opinion of clang developers?
> Is there an option C which is even better?
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.
QualifiedNameType: Should handle all type references that involve qualified names but for which we can resolve the name lookup to actually refer to a specific type. These could actually have "typename" qualifiers on them, but the point is that QualifiedNameType is always sugar.
TypenameType: Should handle all type references that involve qualified names where the name it refers to is a dependent name. May or may not actually have the "typename" keyword.
- Doug
More information about the cfe-dev
mailing list