Hello,<div><br></div><div>I am encountering some odd behavior when writing a Clang frontend action and was hoping someone could explain the behavior I am seeing.</div><div><br></div><div><div>Consider the following code:</div>
<div><br></div><div><font class="Apple-style-span" face="'courier new', monospace">template <typename T></font></div><div><font class="Apple-style-span" face="'courier new', monospace">T identity(T input) {</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace">  return input;</font></div><div><font class="Apple-style-span" face="'courier new', monospace">}</font></div><div><br></div><div>In my frontend action I would like to identify the return type of a function. Which, in the above code should be the template type parameter "T".</div>
<div><br></div><div><font class="Apple-style-span" face="'courier new', monospace">bool MyASTVisitor::VisitFunctionDecl(clang::FunctionDecl* decl) {</font></div><div><font class="Apple-style-span" face="'courier new', monospace">  LG << "Checking function return type (" << decl->getNameAsString() << ")";</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace">  const clang::QualType return_type = decl->getResultType();</font></div><div><font class="Apple-style-span" face="'courier new', monospace"><br>
</font></div><div><font class="Apple-style-span" face="'courier new', monospace">  LG << "Origin decl:";</font></div><div><font class="Apple-style-span" face="'courier new', monospace">  decl->dump();</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div><div><font class="Apple-style-span" face="'courier new', monospace">  LG << "Dumping return type with class name: " << return_type->getTypeClassName();</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace">  return_type->dump();</font></div><div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div><div><font class="Apple-style-span" face="'courier new', monospace">  if (return_type->isTemplateTypeParmType()) {</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace">    const clang::TemplateTypeParmType* template_param_type =</font></div><div><font class="Apple-style-span" face="'courier new', monospace">        return_type->castAs<clang::TemplateTypeParmType>();</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace">    CHECK_NOTNULL(template_param_type);</font></div><div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div>
<div><font class="Apple-style-span" face="'courier new', monospace">    const clang::TemplateTypeParmDecl* template_param_type_decl =</font></div><div><font class="Apple-style-span" face="'courier new', monospace">        template_param_type->getDecl();</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace">    CHECK_NOTNULL(template_param_type_decl);</font></div><div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div>
<div><font class="Apple-style-span" face="'courier new', monospace">    template_param_type_decl->dump();</font></div><div><font class="Apple-style-span" face="'courier new', monospace">  }</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div><div><font class="Apple-style-span" face="'courier new', monospace">  return true;</font></div><div><font class="Apple-style-span" face="'courier new', monospace">}</font></div>
<div><br></div><div>However, TemplateTypeParmType::getDecl always returns NULL. Digging into the Clang code, this is because the template type parameter is 'canonical'. <a href="http://clang.llvm.org/doxygen/Type_8h_source.html#l03073">http://clang.llvm.org/doxygen/Type_8h_source.html#l03073</a></div>
<div><br></div><div><div><font class="Apple-style-span" face="'courier new', monospace">  TemplateTypeParmDecl *getDecl() const {</font></div><div><font class="Apple-style-span" face="'courier new', monospace">    return isCanonicalUnqualified() ? 0 : TTPDecl;</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace">  }</font></div></div><div><br></div><div><meta http-equiv="content-type" content="text/html; charset=utf-8">In this context does canonical actually mean? That the template parameter isn't introduced via a typedef? Is there any way I can massage the QualType in such a way that I can get access to its original declaration and IdentifierInfo?</div>
</div><div><br></div><div>Thanks,</div><div>-Chris</div>