[cfe-dev] Using clang-tool to Exact type names in template specification arguments

Oliver Zhang via cfe-dev cfe-dev at lists.llvm.org
Sun Aug 16 21:41:36 PDT 2020


Thanks David and Dave for your nice suggestions and thoughts!

Unfortunately the case I need to handle is a little more complex than I
thought, as implicit template specification is involved. Now the full
example looks like this (differences from the previous example is
highlighted):

typedef unsigned int vectors32_t[32];
template <typename T>
func(T *const vec) {
    ...
}
int main() {
    ...

    *vector32_t *vecPtr = ...;*

    *func(vecPtr);*
    ...
}


I didn't find a way to get the type alias name ("vector32_t") from
an implicit template argument by using CallExpr or DeclRefExpr. Actually it
seems information about "vector32_t" can only be retrieved from the typedef
and the declaration of "vecPtr".

Best,
Oliver

On Fri, Aug 14, 2020 at 12:20 AM David Rector <davrecthreads at gmail.com>
wrote:

> Yes you’re right, good point.  In the FunctionDecl level the template
> argument types must be canonical.
>
> Oliver definitely take David’s advice to get the template arguments from
> the DeclRefExpr referenced in the CallExpr — hopefully that should contain
> the proper type sugar.
>
> Pratyush, this unfortunately may have the implications for the solution
> you employed in https://reviews.llvm.org/D77598 at my suggestion, in
> order to distinguish between deduced and non-deduced non-type template
> arguments.
>
> I think you should go with the first suggestion I gave you: simply change
> line
> https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaTemplate.cpp#L6823 to
> this:
>
> QualType CanonParamType = Context.getCanonicalType(ParamType);
>
> // Note: this renders CanonParamType non-canonical, but since every
> instantiation
> // of this argument will be wrapped in an AutoType (since Param->getType()
> will always
> // be an AutoType for this template), there should be no difference in how
> arguments
> // are distinguished.
> if (Param->getType()->getAs<AutoType>())
>   CanonParamType = Context.getAutoType(CanonParamType,
> AutoTypeKeyword::Auto,
>                                        false, false);
>
> Good catch, David.
>
> Dave
>
>
> On Aug 13, 2020, at 11:58 AM, David Blaikie <dblaikie at gmail.com> wrote:
>
> On Thu, Aug 13, 2020 at 7:45 AM David Rector <davrecthreads at gmail.com>
> wrote:
>
>
> Correction: I did not notice that was a typename parameter, not a non-type
> template parameter as Pratyush addressed — so the issue is broader.
> Perhaps CheckTemplateArgument(TemplateTypeParmDecl *, …) needs to be
> addressed too, e.g. perhaps in this line the original type should be used
> instead of the canonical type:
>
>
> https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaTemplate.cpp#L6126
>
> That fix, or one like it, would probably solve Oliver’s issue.
>
> More generally there is no reason to be replacing types with their
> canonical types anywhere in the AST, I believe.
>
>
> I believe there is - ultimately there's only one implicit
> specialization of 'f1' (f1<int>, specifically) in code like this:
>
> template<typename T> void f1() { }
> int main() {
>  using x = int;
>  using y = int;
>  f1<x>();
>  f1<y>();
> }
>
> So the FunctionDecl for 'f1' can't refer to x or y, it has to refer to
> 'int', right?
>
>
> - Dave
>
> On Aug 13, 2020, at 10:13 AM, David Rector <davrecthreads at gmail.com>
> wrote:
>
> Ha, deja vu - Pratyush (cc’d) was just dealing with this exact issue in
> another context the other day, and Oliver we were kind of dealing with this
> same general issue the other week re: attributes.
>
> You definitely *should* be able to get the full type sugar without fuss.
> The obstacle to that is in
>
> Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, QualType
> ParamType, …)
>
> linked to here:
> https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaTemplate.cpp#L6688
> .
>
> For some reason within that function the Converted template argument is
> always constructed with Context.getCanonicalType(ParamType), instead of
> ParamType, which erases the type sugar needlessly.
>
> Pratyush has solved this for the C++17 branch of that function in
> https://reviews.llvm.org/D77598, but Pratyush it is probably a good idea
> to replace all other instances of Context.getCanonicalType(XYZ) in that
> function with XYZ, e.g. this line (among others):
>
> https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaTemplate.cpp#L6955
>
> I suspect no tests will be broken with such a change, and the result will
> be that template arguments will always have the proper sugar available.
>
> - Dave
>
> On Aug 13, 2020, at 12:30 AM, David Blaikie via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>
> Once you have the FunctionDecl you've gone too far and any type sugar
> is lost, I believe. (because func<vectors32_t> is the same function as
> func<unsigned int[32]> or any other typedef/alias/etc of that type
> parameter, etc)
>
> I think you'd have to be able to see the call to the function, and go
> from there to find the type as written.
>
> On Wed, Aug 12, 2020 at 8:14 PM Oliver Zhang via cfe-dev
> <cfe-dev at lists.llvm.org> wrote:
>
>
> Hi,
>
> I'm using clang-tool to extract type names in template arguments. For
> example,
>
> typedef unsigned int vectors32_t[32];
> template <typename T>
> func(T *const vec) {
>   ...
> }
> int main() {
>   ...
>   func<vector32_t>(...);
>   ...
> }
>
>
>
> I'd like to get the type name "vector32_t" from func's template argument.
> So I use clang::FunctionDecl::getTemplateSpecializationArgs() to get func's
> template argument list, extract the argument from the list, and then try to
> get the type name for the argument by using
> clang::TemplateArgument::getAsType().getAsString(). However, "unsigned int
> [32]" is returned rather than "vector32_t".
>
> Any thoughts on how I can extract the type alias name "vector32_t" in my
> above example?
>
> Thanks,
> Oliver
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200817/b706d85c/attachment-0001.html>


More information about the cfe-dev mailing list