Currently there's no way to find the UsingDecl that a typeloc found its
underlying type through. Compare to DeclRefExpr::getFoundDecl().
This is critical for some tooling use cases, e.g. finding unused #include directives.
(AST-based approaches to this problem are imperfect, but nevertheless useful).
Moreover in general clang does retain such sugar in the AST.
Design decisions:
- a sugar type, as there are many contexts this type of use may appear in
- UsingType is a leaf like TypedefType, the underlying type has no TypeLoc
- not unified with UnresolvedUsingType: a single name is appealing, but being sometimes-sugar is often fiddly.
- not unified with TypedefType: the UsingShadowDecl is not a TypedefNameDecl or even a TypeDecl, and users think of these differently.
- does not cover other rarer aliases like objc @compatibility_alias, in order to be have a concrete API that's easy to understand.
Scope:
- This does not cover types associated with template names introduced by using declarations. A future patch should introduce a sugar TemplateName variant for this. (CTAD deduced types fall under this)
- There are enough AST matchers to fix the in-tree clang-tidy tests and probably any other matchers, though more may be useful later.
Downsides:
- This changes a common pattern in the AST people likely depend on matching. Previously, typeLoc(loc(recordType())) matched whether a struct was referred to by its original scope or introduced via using-decl. Now, the using-decl case is not matched, and needs a separate matcher. This is similar to the case of typedefs but nevertheless both adds complexity and breaks existing code.
I believe you mentioned ObjC considerations might require expanding beyond UsingShadowDecl as the type of Found -- is that why this is a generic NamedDecl? I.e. can Found indeed be other things than a UsingShadowDecl?