[cfe-dev] Help with integral template argument suffix and cast printing

Pratyush Das via cfe-dev cfe-dev at lists.llvm.org
Sun Aug 9 04:10:54 PDT 2020


That worked! Thanks. I have updated the diff in
https://reviews.llvm.org/D77598.
(I tried to add you as a reviewer, but I was unable to find your
phabricator id)

On Fri, 7 Aug 2020 at 23:53, David Rector <davrecthreads at gmail.com> wrote:

> Actually ParamType may already be constructed with the proper AutoType
> sugar, so just try changing that line to
>
> QualType CanonParamType = ParamType;
>
>
> If that works and doesn’t break any tests, then get rid of CanonParamType
> and replace it with ParamType in that function.
>
> - Dave
>
>
> On Aug 7, 2020, at 2:03 PM, David Rector <davrecthreads at gmail.com> wrote:
>
> You’re not making a mistake, the template argument was not constructed
> with the proper type sugar, which means there’s nothing you can do to
> distinguish deduced from non-deduced template arguments as is.
>
> I think the following will solve it; change line
> https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaTemplate.cpp#L6823 to
> the following:
>
> QualType CanonParamType = Context.getCanonicalType(ParamType);
>
> // FIXME: this renders CanonParamType non-canonical, but…why do we need
> // a canonical type in the first place to construct template args?
> // Seems to just lose type sugar info prematurely.
> if (Param->getType()->getAs<AutoType>())
>   CanonParamType = Context.getAutoType(CanonParamType,
> AutoTypeKeyword::Auto,
>                                        false, false);
>
> See if that gets your thing to work (both T->getAs<AutoType>() and
> T->getAs<BuiltinType>() should return non-null for deduced builtins,
> allowing you to T->getAs<AutoType>() use distinguish deduced from
> non-deduced), then see if it breaks any others tests (it shouldn’t, because
> nothing should depend on template arguments being constructed with a
> canonical type at that point — I think we should be able to get rid of
> CanonParamType and use ParamType in its place in that function).
>
> Good luck,
>
> Dave
>
>
> On Aug 7, 2020, at 8:30 AM, Pratyush Das <reikdas at gmail.com> wrote:
>
> This is where we get the Integral type from the TemplateArgument -
> https://github.com/llvm/llvm-project/blob/master/clang/lib/AST/TemplateBase.cpp#L55
> .
>
> I tried -
> bool flag = false;
> if (auto *autoT = T->getAs<AutoType>()) {
>  flag = true;
> }
>
> But flag is not true for the example -
> template<auto N> struct S {};
> template<> struct S<1> { using type = int };
> S<1L>::type t;
>
> Am I making a mistake in getting the AutoType?
>
> On Wed, 22 Jul 2020 at 20:23, David Rector <davrecthreads at gmail.com>
> wrote:
>
>> The issue may be that the proper sugar isn’t being stored in the integral
>> type when the TemplateArgument is created, so that there is no way to
>> distinguish a non-deduced BuiltInType from a deduced one.
>>
>> The type of the NonTypeTemplateParmDecl N in
>>
>> template<auto N> struct S {}` is an AutoType — so far so good.
>>
>> But the type of the integral TemplateArgument '1' in S<1>, though, seems
>> to be a BuiltInType — no sugar atop it, nothing to distinguish it from the
>> situation where N had a BuiltInType instead of an AutoType.
>>
>> If I understand DeducedTypes correctly, when they are substituted, they
>> should remain as sugar atop the substitution (someone correct me if I’m
>> wrong), and that does not seem to happen here.
>>
>> If others agree this is the issue, I would imagine you will have to dig
>> around to figure out where the template argument is being created, and wrap
>> the integral’s type in an AutoType.  Then testing if getAs<DeducedType>()
>> before testing getAs<BuiltInType>() should tell you when your BuiltInType
>> was deduced.
>>
>> That’s my last best guess anyway.  Good luck,
>>
>> Dave
>>
>> On Jul 22, 2020, at 3:53 AM, Pratyush Das <reikdas at gmail.com> wrote:
>>
>> That change does not work :(
>>
>> Thanks though!
>>
>> On Tue, 21 Jul 2020 at 23:30, David Rector <davrecthreads at gmail.com>
>> wrote:
>>
>>>
>>> I would try replacing
>>>
>>>  else if (auto *DT = T->getContainedDeducedType())
>>>
>>> with
>>>
>>>   else if (auto *DT = T->getAs<DeducedType>())
>>>
>>> I think that is what you want anyway, since getContainedDeducedType
>>> seems to look not only through type sugar but through pointee types, array
>>> element types, etc.
>>>
>>> To be sure, your example still should have worked using
>>> getContainedDeducedType but I think GetContainedDeducedTypeVisitor may have
>>> a problem in its implementation: it doesn’t handle all the possible sugar
>>> types.   In this case, you probably have a SubstTemplateTypeParmType, and I
>>> don’t see a VisitSubstTemplateTypeParmType implementation in there
>>> anywhere, so it is probably returning nullptr instead of desugaring and
>>> continuing to search.  That’s my best guess anyway from my perusal.
>>>
>>> If this change works, it is probably another reason to replace stuff
>>> like GetContainedDeducedTypeVisitor with a more advanced getAs<T>(), with
>>> an extra template param that would allow you to look through e.g. pointee
>>> types, element types, function return types etc. when desired.
>>>
>>> If that doesn’t work though, disregard.  Good luck,
>>>
>>> Dave
>>>
>>> On Jul 21, 2020, at 9:06 AM, Pratyush Das via cfe-dev <
>>> cfe-dev at lists.llvm.org> wrote:
>>>
>>> Hi,
>>>
>>> I am a little stuck with https://reviews.llvm.org/D77598 and would
>>> really appreciate any help.
>>>
>>> I am trying to get the proper suffixes in the error messages for the
>>> following two examples -
>>>
>>> template<auto N> struct S {};
>>> template<> struct S<1> { using type = int };
>>> S<1L>::type t;
>>>
>>> which should give the error message with a suffix -
>>> error: no type named 'type' in 'S<1L>'; did you mean 'S<1>::type'?
>>>
>>> and
>>>
>>> template <unsigned long long N> struct enable_if_unsigned_long_long {};
>>> template <> struct enable_if_unsigned_long_long<1> { typedef int type;
>>> };
>>> void test_unsigned_long_long() { enable_if_unsigned_long_long<2>::type
>>> i; }
>>>
>>> which should give no suffix in the error message -
>>> error: no type named 'type' in 'enable_if_unsigned_int<2>'; did you mean
>>> 'enable_if_unsigned_int<1>::type'?
>>>
>>> I am trying to find the correct combination that would enable suffix in
>>> the first case, but not in the second case. I have been tinkering with
>>> checks for DeducedType and DependentType, but always either the suffixes
>>> are disabled for both the cases, or enabled for both the cases.
>>>
>>> Can anyone please provide any insight on how to proceed?
>>>
>>> Thanks!
>>>
>>> --
>>> Pratyush Das(Reik)
>>> _______________________________________________
>>> cfe-dev mailing list
>>> cfe-dev at lists.llvm.org
>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>>
>>>
>>>
>>
>> --
>> Pratyush Das(Reik)
>>
>>
>>
>
> --
> Pratyush Das(Reik)
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200809/bbd83e11/attachment-0001.html>


More information about the cfe-dev mailing list