<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Yes you’re right, good point. In the FunctionDecl level the template argument types must be canonical. <div class=""><br class=""></div><div class="">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. <div class=""><br class=""></div><div class="">Pratyush, this unfortunately may have the implications for the solution you employed in <a href="https://reviews.llvm.org/D77598" class="">https://reviews.llvm.org/D77598</a> at my suggestion, in order to distinguish between deduced and non-deduced non-type template arguments. </div><div class=""><br class=""></div><div class="">I think you should go with the first suggestion I gave you: simply change line <a href="https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaTemplate.cpp#L6823" class="">https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaTemplate.cpp#L6823</a> to this:</div><div class=""><br class=""></div><div class=""><table cellspacing="0" cellpadding="0" class=""><tbody class=""><tr class=""><td valign="top" class="" style="width: 1157.8px; background-color: rgb(255, 251, 213); margin: 0.5px; padding: 0px 10px;"><div class="" style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Menlo; color: rgb(27, 31, 34); background-color: rgb(255, 255, 255);"><span class="" style="-webkit-font-kerning: none;">QualType CanonParamType = Context.</span><span class="" style="-webkit-font-kerning: none; color: rgb(7, 68, 184);">getCanonicalType</span><span class="" style="-webkit-font-kerning: none;">(ParamType);</span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Menlo; color: rgb(27, 31, 34); background-color: rgb(255, 255, 255); min-height: 14px;"><span class="" style="-webkit-font-kerning: none;"></span><br class=""></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Menlo; color: rgb(27, 31, 34); background-color: rgb(255, 255, 255);"><span class="" style="-webkit-font-kerning: none;">// Note: this renders CanonParamType non-canonical, but since every instantiation</span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Menlo; color: rgb(27, 31, 34); background-color: rgb(255, 255, 255);"><span class="" style="-webkit-font-kerning: none;">// of this argument will be wrapped in an AutoType (since Param->getType() will always</span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Menlo; color: rgb(27, 31, 34); background-color: rgb(255, 255, 255);"><span class="" style="-webkit-font-kerning: none;">// be an AutoType for this template), there should be no difference in how arguments </span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Menlo; color: rgb(27, 31, 34); background-color: rgb(255, 255, 255);"><span class="" style="-webkit-font-kerning: none;">// are </span><span class="" style="-webkit-font-kerning: none;">disti</span>nguished.</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Menlo; color: rgb(27, 31, 34); background-color: rgb(255, 255, 255);"><span class="" style="-webkit-font-kerning: none;">if (Param->getType()->getAs<AutoType>())</span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Menlo; color: rgb(27, 31, 34); background-color: rgb(255, 255, 255);"><span class="" style="-webkit-font-kerning: none;"> CanonParamType = Context.getAutoType(CanonParamType, AutoTypeKeyword::Auto,</span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Menlo; color: rgb(27, 31, 34); background-color: rgb(255, 255, 255);"><span class="" style="-webkit-font-kerning: none;"> false, false);</span></div></td></tr></tbody></table></div><div class=""><br class=""></div><div class="">Good catch, David.</div><div class=""><br class=""></div><div class="">Dave</div><div class=""><br class=""></div><div class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Aug 13, 2020, at 11:58 AM, David Blaikie <<a href="mailto:dblaikie@gmail.com" class="">dblaikie@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">On Thu, Aug 13, 2020 at 7:45 AM David Rector <<a href="mailto:davrecthreads@gmail.com" class="">davrecthreads@gmail.com</a>> wrote:<br class=""><blockquote type="cite" class=""><br class="">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:<br class=""><br class=""><a href="https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaTemplate.cpp#L6126" class="">https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaTemplate.cpp#L6126</a><br class=""><br class="">That fix, or one like it, would probably solve Oliver’s issue.<br class=""><br class="">More generally there is no reason to be replacing types with their canonical types anywhere in the AST, I believe.<br class=""></blockquote><br class="">I believe there is - ultimately there's only one implicit<br class="">specialization of 'f1' (f1<int>, specifically) in code like this:<br class=""><br class="">template<typename T> void f1() { }<br class="">int main() {<br class=""> using x = int;<br class=""> using y = int;<br class=""> f1<x>();<br class=""> f1<y>();<br class="">}<br class=""><br class="">So the FunctionDecl for 'f1' can't refer to x or y, it has to refer to<br class="">'int', right?<br class=""><br class=""><blockquote type="cite" class=""><br class="">- Dave<br class=""><br class="">On Aug 13, 2020, at 10:13 AM, David Rector <<a href="mailto:davrecthreads@gmail.com" class="">davrecthreads@gmail.com</a>> wrote:<br class=""><br class="">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.<br class=""><br class="">You definitely *should* be able to get the full type sugar without fuss. The obstacle to that is in<br class=""><br class="">Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, QualType ParamType, …)<br class=""><br class="">linked to here: <a href="https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaTemplate.cpp#L6688" class="">https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaTemplate.cpp#L6688</a>.<br class=""><br class="">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.<br class=""><br class="">Pratyush has solved this for the C++17 branch of that function in <a href="https://reviews.llvm.org/D77598" class="">https://reviews.llvm.org/D77598</a>, 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):<br class=""><a href="https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaTemplate.cpp#L6955" class="">https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaTemplate.cpp#L6955</a><br class=""><br class="">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.<br class=""><br class="">- Dave<br class=""><br class="">On Aug 13, 2020, at 12:30 AM, David Blaikie via cfe-dev <cfe-dev@lists.llvm.org> wrote:<br class=""><br class="">Once you have the FunctionDecl you've gone too far and any type sugar<br class="">is lost, I believe. (because func<vectors32_t> is the same function as<br class="">func<unsigned int[32]> or any other typedef/alias/etc of that type<br class="">parameter, etc)<br class=""><br class="">I think you'd have to be able to see the call to the function, and go<br class="">from there to find the type as written.<br class=""><br class="">On Wed, Aug 12, 2020 at 8:14 PM Oliver Zhang via cfe-dev<br class=""><cfe-dev@lists.llvm.org> wrote:<br class=""><br class=""><br class="">Hi,<br class=""><br class="">I'm using clang-tool to extract type names in template arguments. For example,<br class=""><br class="">typedef unsigned int vectors32_t[32];<br class="">template <typename T><br class="">func(T *const vec) {<br class=""> ...<br class="">}<br class="">int main() {<br class=""> ...<br class=""> func<vector32_t>(...);<br class=""> ...<br class="">}<br class=""><br class=""><br class=""><br class="">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".<br class=""><br class="">Any thoughts on how I can extract the type alias name "vector32_t" in my above example?<br class=""><br class="">Thanks,<br class="">Oliver<br class="">_______________________________________________<br class="">cfe-dev mailing list<br class="">cfe-dev@lists.llvm.org<br class="">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev<br class=""><br class="">_______________________________________________<br class="">cfe-dev mailing list<br class="">cfe-dev@lists.llvm.org<br class="">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev<br class=""><br class=""><br class=""><br class=""></blockquote></div></div></blockquote></div><br class=""></div></div></body></html>