<div dir="ltr">When calling a templated method in the body of another templated method<br>the template argument information of the call gets lost.<br><br>The example below shows this case. The templated test function calls the<br>templated foo function.<br><br>EXAMPLE:<br><br>template <typename U><br>void foo() {<br> //some body...<br>}<br><br>template <typename T><br>void test() {<br> foo<float>();<br>}<br><br>int main() {<br> test<int>();<br> return 0;<br>}<br><br>AST:<br>foo function AST<br><br>FunctionTemplateDecl 0x1618250 </tmp/test3.cpp:1:1, line:4:1> foo<br>|-TemplateTypeParmDecl 0x16180b0 <line:1:11, col:20> typename U<br>|-FunctionDecl 0x16181b0 <line:2:1, line:4:1> foo 'void (void)'<br>| `-CompoundStmt 0x1618298 <line:2:12, line:4:1><br>`-FunctionDecl 0x1661680 <line:2:1, line:4:1> foo 'void (void)'<br>  |-TemplateArgument type 'float'<br>  `-CompoundStmt 0x1618298 <line:2:12, line:4:1><br><br>test function AST<br><br>FunctionTemplateDecl 0x16614a0 <line:6:1, line:9:1> test<br>|-TemplateTypeParmDecl 0x16182b0 <line:6:11, col:20> typename T<br>|-FunctionDecl 0x1618350 <line:7:1, line:9:1> test 'void (void)'<br>| `-CompoundStmt 0x1661868 <line:7:13, line:9:1><br>|   `-CallExpr 0x1661840 <line:8:2, col:13> 'void'<br>|     `-ImplicitCastExpr 0x1661828 <col:2, col:11> 'void (*)(void)' <FunctionToPointerDecay><br>|       `-DeclRefExpr 0x1661780 <col:2, col:11> 'void (void)' lvalue Function 0x1661680 'foo' 'void (void)' (FunctionTemplate 0x1618250 'foo')<br>`-FunctionDecl 0x1661b70 <line:7:1, line:9:1> test 'void (void)'<br>  |-TemplateArgument type 'int'<br>  `-CompoundStmt 0x1661e40 <line:7:13, line:9:1><br>    `-CallExpr 0x1661e18 <line:8:2, col:13> 'void'<br>      `-ImplicitCastExpr 0x1661e00 <col:2, col:11> 'void (*)(void)' <FunctionToPointerDecay><br>        `-DeclRefExpr 0x1661d90 <col:2, col:11> 'void (void)' lvalue Function 0x1661680 'foo' 'void (void)'<br><br>main function AST<br><br>FunctionDecl 0x16618e0 <line:11:1, line:14:1> main 'int (void)'<br>`-CompoundStmt 0x1661d68 <line:11:12, line:14:1><br>  |-CallExpr 0x1661d00 <line:12:2, col:12> 'void'<br>  | `-ImplicitCastExpr 0x1661ce8 <col:2, col:10> 'void (*)(void)' <FunctionToPointerDecay><br>  |   `-DeclRefExpr 0x1661c70 <col:2, col:10> 'void (void)' lvalue Function 0x1661b70 'test' 'void (void)' (FunctionTemplate 0x16614a0 'test')<br>  `-ReturnStmt 0x1661d48 <line:13:2, col:9><br>    `-IntegerLiteral 0x1661d28 <col:9> 'int' 0<br><br>In the AST we can see a template instantiation of test<int> (0x1661b70),<br>and this template instantiation contains a call to foo<float> (0x1661680).<br>This call is visible in the CallExpr (0x1661e18) that captures a<br>DeclRefExpr (0x1661d90). The problem occurs when checking this DeclRefExpr<br>for explicit template arguments. The call to declRef->hasExplicitTemplateArgs()<br>will always return false (even when it has explicit template arguments), because<br>the template argument information is not passed to the instances of the<br>templated function.<br><br>In TreeTransform.h method RebuildDeclRefExpr<br>we can find a FIXME comment that says: loses template args.<br>The following patch should solve this issue.<br>Unit tests have been executed like described in <a href="http://clang.llvm.org/hacking.html">http://clang.llvm.org/hacking.html</a><br>and <a href="http://llvm.org/docs/TestingGuide.html#testsuiterun">http://llvm.org/docs/TestingGuide.html#testsuiterun</a>. I hope this is the correct<br>way to test that the patch doesn't break anything else?!<br><br>Cheers,<br>Stefan Moosbrugger<br></div>