<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=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Apr 23, 2019, at 3:48 PM, Frederic Riss via Phabricator <<a href="mailto:reviews@reviews.llvm.org" class="">reviews@reviews.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">friss created this revision.<br class="">friss added reviewers: shafik, clayborg, jingham.<br class="">Herald added subscribers: kristof.beyls, javed.absar, aprantl.<br class=""><br class="">When we encounter a templated function in the debug information, we<br class="">were creating an AST that looked like this:<br class=""><br class="">FunctionTemplateDecl 0x12980ab90 <<invalid sloc>> <invalid sloc> foo<int><br class=""><br class="">| -TemplateTypeParmDecl 0x12980aad0 <<invalid sloc>> <invalid sloc> class depth 0 index 0 T |<br class="">| -FunctionDecl 0x12980aa30 <<invalid sloc>> <invalid sloc> foo<int> 'int (int)' extern     |<br class="">|                                                                                           | -TemplateArgument type 'int' |<br class="">| `-ParmVarDecl 0x12980a998 <<invalid sloc>> <invalid sloc> t1 'int'                        |<br class="">|<br class=""><br class="">`-FunctionDecl 0x12980aa30 <<invalid sloc>> <invalid sloc> foo<int> 'int (int)' extern<br class=""><br class="">  |-TemplateArgument type 'int'<br class="">  `-ParmVarDecl 0x12980a998 <<invalid sloc>> <invalid sloc> t1 'int'<br class=""><br class="">Note that the FunctionTemplateDecl has 2 children which are identical (as<br class="">in have the same address). This is not what Clang is doing:<br class=""><br class="">FunctionTemplateDecl 0x7f89d206c6f8 </tmp/template.cpp:1:1, line:4:1> line:2:5 foo<br class=""><br class="">| -TemplateTypeParmDecl 0x7f89d206c4a8 <line:1:10, col:19> col:19 referenced typename depth 0 index 0 T |<br class="">| -FunctionDecl 0x7f89d206c660 <line:2:1, line:4:1> line:2:5 foo 'int (T)'                              |<br class="">| `-ParmVarDecl 0x7f89d206c570 <col:9, col:11> col:11 t1 'T'                                            |<br class="">|<br class=""><br class="">`-FunctionDecl 0x7f89d206cb60 <line:2:1, line:4:1> line:2:5 used foo 'int (int)'<br class=""><br class="">  |-TemplateArgument type 'int'<br class="">  `-ParmVarDecl 0x7f89d206ca68 <col:9, col:11> col:11 t1 'int':’int'<br class=""></div></div></blockquote><div><br class=""></div><div>I don’t know what Phabricator did to my commit message. Here it is (hopefully) un-mangled:</div><div><br class=""></div><div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    Fix infinite recursion when calling C++ template functions</span></div><p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    Summary:</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    When we encounter a templated function in the debug information, we</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    were creating an AST that looked like this:</span></div><p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    FunctionTemplateDecl 0x12980ab90 <<invalid sloc>> <invalid sloc> foo<int></span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    |-TemplateTypeParmDecl 0x12980aad0 <<invalid sloc>> <invalid sloc> class depth 0 index 0 T</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    |-FunctionDecl 0x12980aa30 <<invalid sloc>> <invalid sloc> foo<int> 'int (int)' extern</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    | |-TemplateArgument type 'int'</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    | `-ParmVarDecl 0x12980a998 <<invalid sloc>> <invalid sloc> t1 'int'</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    `-FunctionDecl 0x12980aa30 <<invalid sloc>> <invalid sloc> foo<int> 'int (int)' extern</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">      |-TemplateArgument type 'int'</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">      `-ParmVarDecl 0x12980a998 <<invalid sloc>> <invalid sloc> t1 'int'</span></div><p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    Note that the FunctionTemplateDecl has 2 children which are identical (as</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    in have the same address). This is not what Clang is doing:</span></div><p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    FunctionTemplateDecl 0x7f89d206c6f8 </tmp/template.cpp:1:1, line:4:1> line:2:5 foo</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    |-TemplateTypeParmDecl 0x7f89d206c4a8 <line:1:10, col:19> col:19 referenced typename depth 0 index 0 T</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    |-FunctionDecl 0x7f89d206c660 <line:2:1, line:4:1> line:2:5 foo 'int (T)'</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    | `-ParmVarDecl 0x7f89d206c570 <col:9, col:11> col:11 t1 'T'</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    `-FunctionDecl 0x7f89d206cb60 <line:2:1, line:4:1> line:2:5 used foo 'int (int)'</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">      |-TemplateArgument type 'int'</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">      `-ParmVarDecl 0x7f89d206ca68 <col:9, col:11> col:11 t1 'int':'int'</span></div><p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    The 2 chidlren are different and actually repesent different things: the first</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    one is the unspecialized version and the second one is specialized. (Just looking</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    at the names shows another major difference which is that we create the parent</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    with a name of "foo<int>" when it should be just "foo".)</span></div><p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    The fact that we have those 2 identical children confuses the ClangImporter</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    and generates an infinite recursion (reported in <a href="https://llvm.org/pr41473" class="">https://llvm.org/pr41473</a>).</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    We cannot create the unspecialized version as the debug information doesn't</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    contain a mapping from the template parameters to their use in the prototype.</span></div><p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    This patch just creates 2 different FunctionDecls for those 2 children of the</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    FunctionTemplateDecl. This avoids the infinite recursion and allows us to</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    call functions. As the XFAILs in the added test show, we've still got issues</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    in our handling of templates. I believe they are mostly centered on the fact</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    that we create do not register "foo" as a template, but "foo<int>". This is</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    a bigger change that will need changes to the debug information generation.</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    I believe this change makes sense on its own.</span></div><p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    Reviewers: shafik, clayborg, jingham</span></div><p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    Subscribers: aprantl, javed.absar, kristof.beyls, lldb-commits</span></div><p style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    </span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    Differential Revision: <a href="https://reviews.llvm.org/D61044" class="">https://reviews.llvm.org/D61044</a></span></div></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class="">Fred</span></div></div><br class=""><blockquote type="cite" class=""><div class=""><div class="">The 2 chidlren are different and actually repesent different things: the first<br class="">one is the unspecialized version and the second one is specialized. (Just looking<br class="">at the names shows another major difference which is that we create the parent<br class="">with a name of "foo<int>" when it should be just "foo".)<br class=""><br class="">The fact that we have those 2 identical children confuses the ClangImporter<br class="">and generates an infinite recursion (reported in <a href="https://llvm.org/pr41473" class="">https://llvm.org/pr41473</a>).<br class="">We cannot create the unspecialized version as the debug information doesn't<br class="">contain a mapping from the template parameters to their use in the prototype.<br class=""><br class="">This patch just creates 2 different FunctionDecls for those 2 children of the<br class="">FunctionTemplateDecl. This avoids the infinite recursion and allows us to<br class="">call functions. As the XFAILs in the added test show, we've still got issues<br class="">in our handling of templates. I believe they are mostly centered on the fact<br class="">that we create do not register "foo" as a template, but "foo<int>". This is<br class="">a bigger change that will need changes to the debug information generation.<br class="">I believe this change makes sense on its own.<br class=""><br class=""><br class=""><a href="https://reviews.llvm.org/D61044" class="">https://reviews.llvm.org/D61044</a><br class=""><br class="">Files:<br class="">  packages/Python/lldbsuite/test/lang/cpp/template-function/Makefile<br class="">  packages/Python/lldbsuite/test/lang/cpp/template-function/TestTemplateFunctions.py<br class="">  packages/Python/lldbsuite/test/lang/cpp/template-function/main.cpp<br class="">  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp<br class=""><br class=""><span id="cid:F5AD248D-E1C1-4B83-805D-D9FC223D8492@apple.com"><D61044.196349.patch></span></div></div></blockquote></div><br class=""></body></html>