Where is DeclarationName Used?
DeclarationName is the type of the name stored in NamedDecl. Most
clients won't see much of a difference here, because an
IdentifierInfo* is implicitly convertible to a DeclarationName, and
those *Decl nodes that can only have normal identifiers for names will
still accept an IdentifierInfo*.
Nice.
*Decl nodes with special names---C++ constructors, destructors, and
conversion functions--- will take in a DeclarationName directly, which
will encode the kind of function and additional information needed to
identify the name (e.g., the type of a conversion function). In
addition, ObjCMethodDecl is now a NamedDecl, and its selector will be
stored in NamedDecl's DeclarationName. Conversion functions between
Selector and DeclarationName make this change mainly an implementation
detail
That is a great cleanup!
Efficiency Concerns
DeclarationName is the size of a single pointer. The lower two bits
are used to determine what kind of name this is. We optimize for three
common cases: an IdentifierInfo*, a 0-argument selector, and a
1-argument selector, and in each case the pointer is just a masked
IdentifierInfo*.
In the less-common case, the pointer is a masked
DeclarationNameExtra*, where the DeclarationNameExpr can either be a
multi-argument Objective-C selector (MultiKeywordSelector) or one of
the C++ special names (constructor, destructor, conversion function).
All of these cases need extra storage anyway.
Makes sense.
The encoded integer in DeclarationName is a unique value which can be
efficiently compared for equality. In the case of Objective-C
selectors and the C++ special functions, the DeclarationNameExtra
pointer is uniqued in a separate table (SelectorTable and
DeclarationNameTable, respectively).
Overall, DeclarationName should be as efficient as an IdentifierInfo*
in both space and time, and as efficient as a Selector for Objective-C
methods. DeclarationName is better than the current hack involving
creating special identifiers for constructors, destructors, and
conversion functions, and will make future work in the area of
conversion functions easier (see below).
Sounds like a win all around,
Known Issues
There's a small layering violation in DeclarationName. DeclarationName
lives in the AST, because that's where it makes sense to talk about
the name of a declaration as a more abstract entity. However,
DeclarationNameExtras and Selector live in Basic, because Selector is
used in the Parse-Sema interaction and Selector's internal
implementation depends on DeclarationNameExtras.
I'm missing something: how is that a layering violation? From your description, it sounds like Sema will depend on Basic. That is ok, but basic can't depend on sema.
We could move DeclarationName into Basic and make the QualType stored
by a C++ constructor/destructor/conversion function into an opaque
type pointer, but that seems wrong somehow. Maybe the real issue is
that Selector doesn't belong in Basic.
I'd be open to moving Selector up the stack, but this will impact ObjC actions callbacks that really do want to pass around selectors (iirc). Another options is to introduce a parser-level abstraction similar to declspec if that were needed. There are some other less appetizing options as well if this is a real problem.
Future Work
Right now, IdentifierResolver still traffics in IdentifierInfo
pointers, and declarations with non-identifier names are never pushed
into a scope. That may change with conversion functions, in which case
the IdentifierResolver will need to work with DeclarationNames. This
should only require a small tweak, so that we have a FETokenInfo field
that is accessible through a DeclarationName. It would, of course, not
be stored in DeclarationName itself but in its IdentifierInfo*
(FETokenInfo is already there) or its DeclarationNameExtras* (we would
need to add it here).
I think Argiris is far more qualified to know the implications of this than I am 
I'll take a look at the patch shortly after lunch, the description makes a lot of sense to me. Thanks a lot for tackling this Doug!
-Chris