[PATCH] PR10405 Missing actual type (aka) in error message when using decltype as a template parameter

Richard Smith richard at metafoo.co.uk
Wed Jul 16 16:37:13 PDT 2014


================
Comment at: lib/AST/ASTDiagnostic.cpp:70-81
@@ -69,5 +69,14 @@
+    // or decltype appears anywhere in the type.
     if (const TemplateSpecializationType *TST
-          = dyn_cast<TemplateSpecializationType>(Ty))
-      if (!TST->isTypeAlias())
+        = dyn_cast<TemplateSpecializationType>(Ty)) {
+      for (auto Arg : *TST) {
+          if (Arg.getKind() == TemplateArgument::Type)
+              Desugar(Context, Arg.getAsType(), ShouldAKA);
+          if (ShouldAKA)
+              break;
+      }
+
+      if (!ShouldAKA && !TST->isTypeAlias())
         break;
+    }
 
----------------
Nikola Smiljanić wrote:
> Richard Smith wrote:
> > Nikola Smiljanić wrote:
> > > Richard Smith wrote:
> > > > It'd be better here to rebuild a TemplateSpecializationType that has the desugared template arguments in it.
> > > What exactly do you mean by **rebuild**?
> > I mean, ask the ASTContext to create a new TemplateSpecializationType with the desugared template arguments.
> I thought it'd be obvious why I was doing this after I did it but I guess I should have asked. At first I though this was an optimization, create this QualType now as it will certainly be created later on. But I've noticed that getting the canonical type from sugared type returns  a different type object with same 'spelling'. I know that we're supposed to have only one QualType per type and I'm lost... Is this what you had in mind, and more importantly why?
> 
> 
> ```
>     if (const TemplateSpecializationType *TST =
>             dyn_cast<TemplateSpecializationType>(Ty)) {
>       SmallVector<TemplateArgument, 4> Args;
>       for (TemplateSpecializationType::iterator I = TST->args_begin(),
>                                                 E = TST->args_end();
>            I != E; ++I) {
>         if (I->getKind() == TemplateArgument::Type)
>           Args.push_back(Desugar(Context, I->getAsType(), ShouldAKA));
>         else
>           Args.push_back(*I);
>       }
> 
>       if (ShouldAKA || TST->isTypeAlias()) {
>         QT = Context.getTemplateSpecializationType(
>             TST->getTemplateName(), Args.data(), Args.size(), QT);
>         break;
>       }
>     }
> ```
Yes, that's approximately what I had in mind. This way, we should perform an appropriate amount of desugaring on template arguments, and not just flatten them straight to their canonical types.

Comments on that code:
 * `ShouldAKA` might have been set by something already; track your own variable to determine if you desugared any arguments
 * It would be useful to also desugar non-type template arguments; maybe pick up the canonical TST's template argument if the non-type template argument is in `Expression` form?

http://reviews.llvm.org/D3588






More information about the cfe-commits mailing list