[llvm-branch-commits] [clang] [libcxx] [clang] Preserve Qualifiers and type sugar in TemplateNames (PR #93433)

Matheus Izvekov via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon May 27 10:38:42 PDT 2024


================
@@ -9304,7 +9299,8 @@ TemplateName ASTContext::getAssumedTemplateName(DeclarationName Name) const {
 TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
                                                   bool TemplateKeyword,
                                                   TemplateName Template) const {
-  assert(NNS && "Missing nested-name-specifier in qualified template name");
----------------
mizvekov wrote:

In 'QualifiedTemplateName', there are two qualifiers: The nested name specifier, and the template keyword.

Just as a template might be written without a template keyword qualifier, it can also be written without a nested name qualifier. You can have one, the other, both, or none.

This assert was already wrong in that it was valid to have a template written with template keyword, but written without any nested name. For example an object access to a member template: `p->template foo<...>`.
That is fixed in this patch and you can see that in tests.

When we know how a template was written, we wish to print them as that.

We have a third situation here: A canonical template name, that is, a template which we have no information on how it was written. We want to be able to tell these apart, because we don't wish to print them as if they had no qualifiers. Quite the contrary, we want to synthesize a maximal nested name for them, based on their DC, and print them with that.

Otherwise, there is no in-band NestedNameSpecifier non-null value to indicate an empty nested name. Null is what we use here, and what is used in other places, like for example the aforementioned ElaboratedType.

In fact, as I mentioned before, this issue is much similar to what we had for ElaboratedType before https://reviews.llvm.org/D112374, except in that case we already recognized that a class name might be written with elaboration, but no nested name, unlike here which the 'only a template keyword' situation was forgotten.

In that case, a `nullptr` was already used to represent an empty NestedNameSpecifier, as expected.

https://github.com/llvm/llvm-project/pull/93433


More information about the llvm-branch-commits mailing list